clap_adapters/
yaml.rs

1use serde::de::DeserializeOwned;
2
3use crate::prelude::FromReader;
4
5/// An adapter for deserializing a Yaml document from a buffered reader
6#[derive(Debug, Clone)]
7pub struct YamlOf<T>(pub T);
8impl<T: DeserializeOwned> FromReader for YamlOf<T> {
9    type Error = serde_yaml::Error;
10    fn from_reader(reader: &mut impl std::io::BufRead) -> Result<Self, Self::Error> {
11        let yaml = serde_yaml::from_reader(reader)?;
12        Ok(YamlOf(yaml))
13    }
14}
15
16impl<T> crate::fs::PathTo<YamlOf<T>> {
17    /// Returns reference to the inner Yaml datatype
18    ///
19    /// # Example
20    ///
21    /// ```
22    /// # fn main() -> anyhow::Result<()> {
23    /// use clap::Parser;
24    /// use clap_adapters::prelude::*;
25    ///
26    /// #[derive(Debug, Parser)]
27    /// struct Cli {
28    ///     #[clap(long)]
29    ///     config: PathTo<YamlOf<serde_json::Value>>,
30    /// }
31    ///
32    /// // Create a config file in a temporary directory
33    /// let config_dir = tempfile::tempdir()?;
34    /// let config_path = config_dir.path().join("config.json");
35    /// let config_path_string = config_path.display().to_string();
36    ///
37    /// // Write a test config to the config file
38    /// let config_string = r#"hello: "world""#;
39    /// std::fs::write(&config_path, &config_string)?;
40    ///
41    /// // Parse our CLI, passing our config file path to --config
42    /// let cli = Cli::parse_from(["app", "--config", &config_path_string]);
43    /// let data = cli.config.data();
44    ///
45    /// // We should expect the value we get to match what we wrote to the config
46    /// assert_eq!(data, &serde_json::json!({"hello":"world"}));
47    /// # Ok(())
48    /// # }
49    /// ```
50    pub fn data(&self) -> &T {
51        &self.data.0
52    }
53
54    /// Returns the owned inner datatype parsed from Yaml
55    ///
56    /// # Example
57    ///
58    /// ```
59    /// # fn main() -> anyhow::Result<()> {
60    /// use clap::Parser;
61    /// use clap_adapters::prelude::*;
62    ///
63    /// #[derive(Debug, Parser)]
64    /// struct Cli {
65    ///     #[clap(long)]
66    ///     config: PathTo<YamlOf<serde_json::Value>>,
67    /// }
68    ///
69    /// // Create a config file in a temporary directory
70    /// let config_dir = tempfile::tempdir()?;
71    /// let config_path = config_dir.path().join("config.json");
72    /// let config_path_string = config_path.display().to_string();
73    ///
74    /// // Write a test config to the config file
75    /// let config_string = r#"hello: "world""#;
76    /// std::fs::write(&config_path, &config_string)?;
77    ///
78    /// // Parse our CLI, passing our config file path to --config
79    /// let cli = Cli::parse_from(["app", "--config", &config_path_string]);
80    /// let data = cli.config.into_data();
81    ///
82    /// // We should expect the value we get to match what we wrote to the config
83    /// assert_eq!(data, serde_json::json!({"hello":"world"}));
84    /// # Ok(())
85    /// # }
86    /// ```
87    pub fn into_data(self) -> T {
88        self.data.0
89    }
90}