$( $x ),+
}
- impl_enum_decodable!($e, $( $x ),+);
+ impl_enum_serialize_and_deserialize!($e, $( $x ),+);
}
}
// Just like the Config struct but with each property wrapped
// as Option<T>. This is used to parse a rustfmt.toml that doesn't
// specity all properties of `Config`.
- // We first parse into `ParsedConfig`, then create a default `Config`
- // and overwrite the properties with corresponding values from `ParsedConfig`
- #[derive(Deserialize, Clone)]
- pub struct ParsedConfig {
+ // We first parse into `PartialConfig`, then create a default `Config`
+ // and overwrite the properties with corresponding values from `PartialConfig`.
+ #[derive(Deserialize, Serialize, Clone)]
+ struct PartialConfig {
$(pub $i: Option<$ty>),+
}
}
)+
- fn fill_from_parsed_config(mut self, parsed: ParsedConfig) -> Config {
+ fn fill_from_parsed_config(mut self, parsed: PartialConfig) -> Config {
$(
if let Some(val) = parsed.$i {
self.$i = val;
}
}
+ pub fn used_to_toml(&self) -> Result<String, String> {
+ let mut partial = PartialConfig {
+ $(
+ $i: if self.tracker.was_accessed(stringify!($i)) {
+ Some(self.$i.clone())
+ } else {
+ None
+ },
+ )+
+ };
+
+ // file_lines is special and can't be specified in toml.
+ partial.file_lines = None;
+
+ toml::to_string(&partial)
+ .map_err(|e| format!("Could not output config: {}", e.to_string()))
+ }
+
+ pub fn to_toml(&self) -> Result<String, String> {
+ let mut partial = PartialConfig {
+ $(
+ $i: Some(self.$i.clone()),
+ )+
+ };
+
+ // file_lines is special and can't be specified in toml.
+ partial.file_lines = None;
+
+ toml::to_string(&partial)
+ .map_err(|e| format!("Could not output config: {}", e.to_string()))
+ }
+
pub fn override_value(&mut self, key: &str, val: &str)
-> result::Result<(), Box<error::Error + Send + Sync>>
{
}
}
+// We also want to avoid attempting to serialize a FileLines to toml. The
+// `Config` struct should ensure this impl is never reached.
+impl ::serde::ser::Serialize for FileLines {
+ fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
+ where S: ::serde::ser::Serializer
+ {
+ panic!("FileLines cannot be serialized. This is a rustfmt bug.");
+ }
+}
+
#[cfg(test)]
mod test {
use super::Range;
Mixed,
}
-impl_enum_decodable!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);
+impl_enum_serialize_and_deserialize!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SeparatorTactic {
Vertical,
}
-impl_enum_decodable!(SeparatorTactic, Always, Never, Vertical);
+impl_enum_serialize_and_deserialize!(SeparatorTactic, Always, Never, Vertical);
impl SeparatorTactic {
pub fn from_bool(b: bool) -> SeparatorTactic {
}
}
-// Macro for deriving implementations of Decodable for enums
+// Macro for deriving implementations of Serialize/Deserialize for enums
#[macro_export]
-macro_rules! impl_enum_decodable {
+macro_rules! impl_enum_serialize_and_deserialize {
( $e:ident, $( $x:ident ),* ) => {
+ impl ::serde::ser::Serialize for $e {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where S: ::serde::ser::Serializer
+ {
+ use serde::ser::Error;
+
+ // We don't know whether the user of the macro has given us all options.
+ #[allow(unreachable_patterns)]
+ match *self {
+ $(
+ $e::$x => serializer.serialize_str(stringify!($x)),
+ )*
+ _ => {
+ Err(S::Error::custom(format!("Cannot serialize {:?}", self)))
+ }
+ }
+ }
+ }
+
impl<'de> ::serde::de::Deserialize<'de> for $e {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where D: ::serde::Deserializer<'de> {