summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2023-10-22 18:43:23 +0200
committerGitHub <noreply@github.com>2023-10-22 18:43:23 +0200
commit05f7d1e8bf5c188d0093a1c8a5cc749ed0177ed6 (patch)
tree45becf0614f32e03005f72329ac6cf534c1c893c
parent6946069755e4bc75af9b7ca678da66c055a0af16 (diff)
parentb78bad6d6055485da84e11132ecb171b054228c1 (diff)
Merge pull request #479 from Elsoberanold/master
docs: Example for conditionally loading sources
-rw-r--r--README.md2
-rw-r--r--examples/custom_file_format/files/private.pem27
-rw-r--r--examples/custom_file_format/files/public.pem9
-rw-r--r--examples/custom_file_format/main.rs73
-rw-r--r--examples/custom_str_format/main.rs (renamed from examples/custom_format/main.rs)0
5 files changed, 110 insertions, 1 deletions
diff --git a/README.md b/README.md
index badab89..daa762b 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ config = "0.13.1"
Library provides out of the box support for most renowned data formats such as JSON or Yaml. Nonetheless, it contains an extensibility point - a `Format` trait that, once implemented, allows seamless integration with library's APIs using custom, less popular or proprietary data formats.
-See [custom_format](https://github.com/mehcode/config-rs/tree/master/examples/custom_format) example for more information.
+See [custom_file_format](https://github.com/mehcode/config-rs/tree/master/examples/custom_file_format) example for more information.
### More
diff --git a/examples/custom_file_format/files/private.pem b/examples/custom_file_format/files/private.pem
new file mode 100644
index 0000000..8ba1118
--- /dev/null
+++ b/examples/custom_file_format/files/private.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA7P+5Ow3YfQJJ0W4DhwdJRUWi1cYOen7qQ+XPAtFOdbJcvIZe
+T+D+fEENDpkDM+lOE1KtpehW4JOZ13ePLM0phktEf9hT1aB0Zc5LXB3M4YuW+lAW
+iXF9moHWxa2DlpyGck7cSlVVKbdljP9AQOzMdTXi3JJUWlnqjeUSINnBqCW21nOh
+frUZZbqBKOx7/iEgjdAsR7K5WAyVIXgbIipCAgWWjP3ejUjrl20QpXu06dGQF8O8
+S7ztwLwtmdUJ5SBrhiub1Ocjr+DSUvIg8kOzUp9gQiMtV8RGTr4W0Bfr75ZwgAfC
+oDNZ+D9S/rlZX0eJJd5rMobiQRE8qBk2oxWcxwIDAQABAoIBAQCtP3MEvGZZW+bi
+de2WM7lYLkOOyi2jVkuiPshJYwBcAXrRRdiDxBHEezk0Rp6UwCQW9AWEloeLu9pm
+LDw5n/CO/06ftl/ydk0gbuGgARjYd9ZyPUF8T75lyCxcbS8YVmvh+8wFesO6rxpJ
+K/6od3Iu7KleXInVUo2oFKBf608pvp/80oSvCeNCK9vh64UUZnm2PfhzD47jYE+u
+QEM/Ceb4LZ/6jf3SqXi/PpZu/IfDqc7JaBkuGIh4Zv+EQuSh6MYvkkn/51PmqOvf
+KM+bCo8U6sGzvQkMJKDUXFPfTeKCaRFdYgYDm94CCGgaMtMUBt+lm2vG2tNuKH0b
+a/J+x1ZBAoGBAPelu0V2T0Wg8WKjI6nbIWRbuPImAp35WyPikchqmi3hpnP68VxG
+D9z0TNmfr5TAajKQ11SSReIEiwJPOwq1/5v0xmqYdhyWX2alAQq5xUAfJzMDN2Rg
+ftO4qMcNoVeH4wAMwXc1gdRHjqWNZrz381y3Z4K/VWOm+BbG7JrejeE/AoGBAPT+
+DLc///zfBEA94m6/I/78jL/+SsLM7LflPByO7JNrsQTm6mo1DvluGYmE34TP8aTb
+dvt5KXb8gpsKS3Z9vD6FJTB0dNrSpTWEPKFTTp/VWTvwHuh8mF/r1KyngDW3IU3q
+7mKkVHMrfnU23qYHODJDnS6WmL3X3tJJAUXDqlp5AoGAR/VlRBrLj/zjBvlGbJ2a
+x1GLnPkEe6iwHe5A1A59vGU7+6loJprJEzf9eKLY3w1GDmld2FokajdNuR8Sldsq
+acOnP+QLNeVP1UCO2/H86dPjjQQbPVR4pcabbDN+tTNr92C9eokWr3sXbO14c+JM
+WZ2FO02jXzBuGBg3Ogz/BvsCgYEA69lCfotTMam0mu+4c2r5CTkxeocgi6Xh4SsC
+km+ZGlabJJ/0XWhU0RUH6paK432YIF/SjEbY/x4Z0Y24lgp3VSyyX5JNCHeu6fUy
+tQ/Q6hfmfsgryR5hRj5vEAN0bsGsgyk+cqHGVtUxOUAoWWcr11+2CqqZwnD1pjT3
+z6SM8+kCgYEA3GPFdb/ILXwPSEFfHE5RGWa2jlns+xVvQTaymR6ZAtLPv2RkBKvw
+Hwy8maCmWgw0+U/f8nMUDPVYYa/5Tyk5UzEVhtbAXGYzyY+Nk4IBFZZ+8P95RJBL
+8jqfXxr2ZpYf9mEgZI8v8Pr013R3Vqkpy+B8jlfpvxFdOwSzkY42ur4=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/custom_file_format/files/public.pem b/examples/custom_file_format/files/public.pem
new file mode 100644
index 0000000..f9420a1
--- /dev/null
+++ b/examples/custom_file_format/files/public.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7P+5Ow3YfQJJ0W4DhwdJ
+RUWi1cYOen7qQ+XPAtFOdbJcvIZeT+D+fEENDpkDM+lOE1KtpehW4JOZ13ePLM0p
+hktEf9hT1aB0Zc5LXB3M4YuW+lAWiXF9moHWxa2DlpyGck7cSlVVKbdljP9AQOzM
+dTXi3JJUWlnqjeUSINnBqCW21nOhfrUZZbqBKOx7/iEgjdAsR7K5WAyVIXgbIipC
+AgWWjP3ejUjrl20QpXu06dGQF8O8S7ztwLwtmdUJ5SBrhiub1Ocjr+DSUvIg8kOz
+Up9gQiMtV8RGTr4W0Bfr75ZwgAfCoDNZ+D9S/rlZX0eJJd5rMobiQRE8qBk2oxWc
+xwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/examples/custom_file_format/main.rs b/examples/custom_file_format/main.rs
new file mode 100644
index 0000000..cc919ca
--- /dev/null
+++ b/examples/custom_file_format/main.rs
@@ -0,0 +1,73 @@
+use config::{Config, File, FileStoredFormat, Format, Map, Value, ValueKind};
+use std::io::{Error, ErrorKind};
+
+/// The private and public key sources will be read into their associated variable:
+#[derive(serde::Deserialize, Clone, Debug)]
+pub struct Settings {
+ pub private_key: Option<String>,
+ pub public_key: Option<String>,
+}
+
+fn main() {
+ // Sourcing from two separate files for the `Settings` struct,:
+ let file_public_key = File::new("examples/custom_file_format/files/public.pem", PemFile);
+ let file_private_key = File::new("examples/custom_file_format/files/private.pem", PemFile);
+
+ // Provide the sources and build the config object:
+ // Both are marked as optional to avoid failure if the file doesn't exist.
+ let settings = Config::builder()
+ .add_source(file_public_key.required(false))
+ .add_source(file_private_key.required(false))
+ .build()
+ .unwrap();
+
+ // Deserialize the config object into your Settings struct:
+ let settings: Settings = settings.try_deserialize().unwrap();
+ println!("{:#?}", settings);
+}
+
+#[derive(Debug, Clone)]
+pub struct PemFile;
+
+impl Format for PemFile {
+ fn parse(
+ &self,
+ uri: Option<&String>,
+ text: &str,
+ ) -> Result<Map<String, config::Value>, Box<dyn std::error::Error + Send + Sync>> {
+ // Store any valid keys into this map, they'll be merged with other sources into the final config map:
+ let mut result = Map::new();
+
+ // Identify the PEM encoded data type by the first occurrence found:
+ // NOTE: This example is kept simple, multiple or other encoded types are not handled.
+ let key_type = vec!["PUBLIC", "PRIVATE"]
+ .into_iter()
+ .find(|s| text.contains(s));
+ let key = match key_type {
+ Some("PRIVATE") => "private_key",
+ Some("PUBLIC") => "public_key",
+ // Otherwise fail with an error message (the filename is implicitly appended):
+ _ => {
+ return Err(Box::new(Error::new(
+ ErrorKind::InvalidData,
+ "PEM file did not contain a Private or Public key",
+ )))
+ }
+ };
+
+ result.insert(
+ key.to_owned(),
+ Value::new(uri, ValueKind::String(text.into())),
+ );
+
+ Ok(result)
+ }
+}
+
+// A slice of extensions associated to this format, when an extension
+// is omitted from a file source, these will be tried implicitly:
+impl FileStoredFormat for PemFile {
+ fn file_extensions(&self) -> &'static [&'static str] {
+ &["pem"]
+ }
+}
diff --git a/examples/custom_format/main.rs b/examples/custom_str_format/main.rs
index 4da2e9d..4da2e9d 100644
--- a/examples/custom_format/main.rs
+++ b/examples/custom_str_format/main.rs