rpkl_jdx/lib.rs
1use pkl::Deserializer;
2use pkl::PklSerialize;
3
4pub mod api;
5mod context;
6pub mod error;
7mod internal;
8pub mod pkl;
9mod utils;
10pub mod value;
11
12pub use error::{Error, Result};
13
14pub use api::evaluator::EvaluatorOptions;
15use utils::macros::_trace;
16pub use value::PklValue as Value;
17
18/// Evaluates a `.pkl` file and deserializes it as `T`. If you need to pass options to the evaluator, such as properties, use [`from_config_with_options`].
19///
20/// `path`: The path to the `.pkl` file
21///
22/// # Example
23///
24/// ```ignore
25/// ip = "127.0.0.1"
26/// database {
27/// username = "root"
28/// password = "password"
29/// }
30/// ```
31/// -------------
32/// ```no_run
33///
34/// use serde::Deserialize;
35///
36/// #[derive(Deserialize)]
37/// struct Config {
38/// ip: String,
39/// database: Database,
40/// }
41///
42/// #[derive(Deserialize)]
43/// struct Database {
44/// username: String,
45/// password: String,
46/// }
47///
48/// # fn main() -> Result<(), rpkl::Error> {
49/// let config: Config = rpkl::from_config("config.pkl")?;
50/// # Ok(())
51/// # }
52/// ```
53pub fn from_config<T>(path: impl AsRef<std::path::Path>) -> Result<T>
54where
55 T: Sized + for<'de> serde::Deserialize<'de>,
56{
57 return from_config_with_options(path, EvaluatorOptions::default());
58}
59
60/// Allows for passing options to the evaluator, such as properties (e.g. `read("prop:username")`). See [`EvaluatorOptions`] for more information.
61///
62/// # Example
63///
64/// ```ignore
65/// ip = "127.0.0.1"
66/// credentials {
67/// username = read("prop:username")
68/// password = read("prop:password")
69/// }
70/// ```
71/// -------------
72/// ```no_run
73///
74/// use serde::Deserialize;
75/// use rpkl::api::evaluator::EvaluatorOptions;
76///
77/// #[derive(Deserialize)]
78/// struct Config {
79/// ip: String,
80/// database: Credentials,
81/// }
82///
83/// #[derive(Deserialize)]
84/// struct Credentials {
85/// username: String,
86/// password: String,
87/// }
88///
89/// # fn main() -> Result<(), rpkl::Error> {
90/// let options = EvaluatorOptions::default()
91/// .properties([("username", "root"), ("password", "password123")]);
92/// let config: Config = rpkl::from_config("config.pkl")?;
93/// # Ok(())
94/// # }
95/// ```
96pub fn from_config_with_options<T>(
97 path: impl AsRef<std::path::Path>,
98 options: EvaluatorOptions,
99) -> Result<T>
100where
101 T: Sized + for<'de> serde::Deserialize<'de>,
102{
103 #[cfg(feature = "trace")]
104 {
105 use tracing::Level;
106 use tracing_subscriber::FmtSubscriber;
107
108 let subscriber = tracing_subscriber::FmtSubscriber::builder()
109 .with_max_level(Level::TRACE)
110 .finish();
111 tracing::subscriber::set_global_default(subscriber)
112 .expect("setting default subscriber failed");
113 }
114
115 let mut evaluator = api::Evaluator::new_from_options(options)?;
116 let pkl_mod = evaluator.evaluate_module(path.as_ref().to_path_buf())?;
117
118 let mut pkld = pkl_mod.serialize_pkl_ast()?;
119
120 _trace!("serialized pkl data {:?}", pkld);
121
122 T::deserialize(&mut Deserializer::from_pkl_map(&mut pkld))
123 .map_err(|e| Error::DeserializeError(format!("{}", e)))
124}