| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- use btlib::bterr;
- // SPDX-License-Identifier: AGPL-3.0-or-later
- use super::DEFAULT_CONFIG;
- use std::{net::IpAddr, path::PathBuf, str::FromStr};
- struct StrParser<'a>(&'a str);
- impl<'a> StrParser<'a> {
- fn assert(&mut self, token: &str) -> btlib::Result<()> {
- if self.0.starts_with(token) {
- self.0 = &self.0[token.len()..];
- Ok(())
- } else {
- Err(bterr!("string does not start with {token}"))
- }
- }
- fn consume_up_to(&mut self, stop: char) -> btlib::Result<&str> {
- let mut count = 0;
- for c in self.0.chars() {
- if c == stop {
- break;
- }
- count += 1;
- }
- let output = &self.0[..count];
- let new_start = self.0.len().min(count + 1);
- self.0 = &self.0[new_start..];
- Ok(output)
- }
- fn remaining(&self) -> &str {
- self.0
- }
- }
- pub enum CredStoreCfg {
- File {
- path: PathBuf,
- },
- Tpm {
- tpm_state_path: PathBuf,
- tabrmd: String,
- },
- }
- impl FromStr for CredStoreCfg {
- type Err = btlib::Error;
- fn from_str(value: &str) -> Result<Self, Self::Err> {
- let mut parser = StrParser(value);
- parser.assert("kind=")?;
- let kind = parser.consume_up_to(',')?;
- match kind {
- "file" => {
- parser.assert("path=")?;
- let path = PathBuf::from(parser.remaining());
- Ok(CredStoreCfg::File { path })
- }
- "tpm" => {
- parser.assert("tpm_state_path=")?;
- let tpm_state_path = PathBuf::from(parser.consume_up_to(',')?);
- let tabrmd = parser.remaining().to_string();
- Ok(CredStoreCfg::Tpm {
- tpm_state_path,
- tabrmd,
- })
- }
- _ => Err(bterr!(
- "unrecognized CredStore kind (expected 'file' or 'tpm'): {kind}"
- )),
- }
- }
- }
- pub struct Config {
- pub cred_store_cfg: CredStoreCfg,
- pub ip_addr: IpAddr,
- pub block_dir: PathBuf,
- }
- impl Config {
- pub fn builder() -> ConfigBuilder {
- ConfigBuilder::new()
- }
- }
- trait OptionExt<'a> {
- fn str_unwrap_or(self, default: &'a str) -> &'a str;
- }
- impl<'a> OptionExt<'a> for &'a Option<String> {
- fn str_unwrap_or(self, default: &'a str) -> &'a str {
- self.as_ref().map(|e| e.as_str()).unwrap_or(default)
- }
- }
- #[derive(Default)]
- pub struct ConfigBuilder {
- pub cred_store: Option<String>,
- pub ip_addr: Option<String>,
- pub block_dir: Option<String>,
- }
- impl ConfigBuilder {
- pub fn new() -> Self {
- Self::default()
- }
- pub fn with_cred_store(mut self, cred_store: Option<String>) -> Self {
- self.cred_store = cred_store;
- self
- }
- pub fn with_ip_addr(mut self, ip_addr: Option<String>) -> Self {
- self.ip_addr = ip_addr;
- self
- }
- pub fn with_block_dir(mut self, block_dir: Option<String>) -> Self {
- self.block_dir = block_dir;
- self
- }
- pub fn build(self) -> Config {
- let cred_store_cfg =
- CredStoreCfg::from_str(self.cred_store.str_unwrap_or(DEFAULT_CONFIG.cred_store))
- .unwrap();
- let ip_addr = IpAddr::from_str(self.ip_addr.str_unwrap_or(DEFAULT_CONFIG.ip_addr)).unwrap();
- let block_dir = PathBuf::from(self.block_dir.str_unwrap_or(DEFAULT_CONFIG.block_dir));
- Config {
- cred_store_cfg,
- ip_addr,
- block_dir,
- }
- }
- }
- pub struct ConfigRef<'a> {
- pub cred_store: &'a str,
- pub ip_addr: &'a str,
- pub block_dir: &'a str,
- }
- pub struct Envvars<'a> {
- pub cred_store: &'a str,
- pub ip_addr: &'a str,
- pub block_dir: &'a str,
- }
|