#![doc=include_str!("../examples/config.toml")]
use serde::Deserialize;
use std::fs;
#[derive(Deserialize)]
pub struct Address {
pub address_line: String,
pub city: String,
pub post_code: String,
pub country_code: String,
}
#[derive(Deserialize)]
pub struct Supplier {
pub name: String,
pub tax_identification: String,
pub address: Address,
pub phone: String,
pub email: String,
pub iban: String,
pub bic: String,
}
#[derive(Deserialize)]
pub struct Buyer {
pub name: String,
pub tax_identification: String,
pub address: Address,
pub email: String,
pub reference: String,
pub due_after_days: i16,
}
#[derive(Deserialize)]
struct CompleteConfig {
pub currency: String,
pub vat_percent: f32,
pub supplier: Supplier,
pub buyer: Vec<Buyer>,
}
pub struct Config {
pub currency: String,
pub vat_percent: f32,
pub supplier: Supplier,
pub buyer: Buyer,
}
pub fn load(filename: &str, buyer_name: &str) -> Result<Config, Box<dyn std::error::Error>> {
let config_toml = fs::read_to_string(filename)?;
let complete_config: CompleteConfig = toml::from_str(&config_toml)?;
let matching_supplier: Option<Buyer> = complete_config
.buyer
.into_iter()
.filter(|x| x.name == buyer_name)
.collect::<Vec<_>>()
.pop();
let matching_supplier = matching_supplier.ok_or(format!(
"Could not find buyer '{buyer_name}' in the configuration file."
))?;
let config = Config {
currency: complete_config.currency,
vat_percent: complete_config.vat_percent,
supplier: complete_config.supplier,
buyer: matching_supplier,
};
Ok(config)
}
#[cfg(test)]
mod tests {
#[test]
fn test_load_config_file() {
let config = crate::config::load("examples/config.toml", "Client Company").unwrap();
assert_eq!(config.supplier.name, "Hans Muster");
assert_eq!(config.buyer.name, "Client Company");
assert_eq!(config.buyer.email, "mail@client1.example.com");
let config = crate::config::load("examples/config.toml", "Another Client").unwrap();
assert_eq!(config.supplier.name, "Hans Muster");
assert_eq!(config.buyer.name, "Another Client");
assert_eq!(config.buyer.email, "mail@client2.example.com");
}
#[test]
fn test_error_on_missing_file() {
assert!(crate::config::load("examples/config_nonexistent.toml", "Client Company").is_err());
}
#[test]
fn test_error_on_missing_buyer() {
assert!(crate::config::load("examples/config.toml", "Wrong Company").is_err());
}
}