From b78bad6d6055485da84e11132ecb171b054228c1 Mon Sep 17 00:00:00 2001 From: Elsoberanold <42942305+Elsoberanold@users.noreply.github.com> Date: Fri, 20 Oct 2023 23:19:26 +0100 Subject: [PATCH] Added read pem files example Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Signed-off-by: Elsoberanold <42942305+Elsoberanold@users.noreply.github.com> Signed-off-by: Matthias Beyer --- README.md | 2 +- examples/custom_file_format/files/private.pem | 27 +++++++ examples/custom_file_format/files/public.pem | 9 +++ examples/custom_file_format/main.rs | 73 +++++++++++++++++++ .../main.rs | 0 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 examples/custom_file_format/files/private.pem create mode 100644 examples/custom_file_format/files/public.pem create mode 100644 examples/custom_file_format/main.rs rename examples/{custom_format => custom_str_format}/main.rs (100%) diff --git a/README.md b/README.md index badab891..daa762b5 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 00000000..8ba11188 --- /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 00000000..f9420a1d --- /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 00000000..cc919ca8 --- /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, + pub public_key: Option, +} + +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, Box> { + // 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 similarity index 100% rename from examples/custom_format/main.rs rename to examples/custom_str_format/main.rs