//#[macro_use]
use preftool::*;
use preftool_derive::*;

struct SomeWrapperForReasons(String);

impl Options for SomeWrapperForReasons {
  fn bind_config<C: ::preftool::Configuration>(
    &mut self,
    config: &C,
  ) -> ::preftool::ValidationResult<()> {
    Options::bind(&mut self.0, config)
  }

  fn validate(&self) -> ::preftool::ValidationResult<()> {
    Ok(())
  }
}

impl FromConfig for SomeWrapperForReasons {
  fn from_config<C: Configuration>(config: &C) -> ValidationResult<Self> {
    let mut ret = SomeWrapperForReasons(String::new());
    ret.bind(config)?;
    Ok(ret)
  }
}

impl Into<String> for SomeWrapperForReasons {
  fn into(self) -> String {
    self.0
  }
}

impl From<String> for SomeWrapperForReasons {
  fn from(s: String) -> Self {
    Self(s)
  }
}

#[derive(Options, PartialEq, Default, Debug)]
struct Simple {
  #[preftool(name = "foo", from = "SomeWrapperForReasons")]
  name: String,
}

#[derive(Options, PartialEq, Default, Debug)]
struct Wrapper {
  nested: Simple,

  #[preftool(flatten)]
  flattened: Simple,
}

#[test]
fn works_with_empty_config() {
  let config = config!();

  let value = Simple::from_config(&config).unwrap();
  assert_eq!(
    value,
    Simple {
      name: "".to_owned()
    }
  );
}

#[test]
fn reads_value_from_config() {
  let config = config!("foo" => "bar");

  let value = Simple::from_config(&config).unwrap();
  assert_eq!(
    value,
    Simple {
      name: "bar".to_owned()
    }
  );
}

#[test]
fn nested_structs() {
  let config = config!(
    "foo" => "flattened",
    "nested:foo" => "nested");

  let value = Wrapper::from_config(&config).unwrap();
  assert_eq!(
    value,
    Wrapper {
      nested: Simple {
        name: "nested".to_owned()
      },
      flattened: Simple {
        name: "flattened".to_owned()
      },
    }
  );
}