ockam_api 0.48.0

Ockam's request-response API
Documentation
use crate::cli_state::{CliState, ProjectConfigCompact, StateDirTrait, StateItemTrait};
use crate::cloud::project::Project;
use crate::config::cli::TrustContextConfig;
use miette::{IntoDiagnostic, WrapErr};
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct TrustContextConfigBuilder {
    pub cli_state: CliState,
    pub project_path: Option<PathBuf>,
    pub trust_context: Option<TrustContextConfig>,
    pub project: Option<String>,
    pub authority_identity: Option<String>,
    pub credential_name: Option<String>,
    pub use_default_trust_context: bool,
}

impl TrustContextConfigBuilder {
    pub fn new(cli_state: &CliState) -> Self {
        Self {
            cli_state: cli_state.clone(),
            project_path: None,
            trust_context: None,
            project: None,
            authority_identity: None,
            credential_name: None,
            use_default_trust_context: false,
        }
    }

    pub fn with_authority_identity(&mut self, authority_identity: Option<&String>) -> &mut Self {
        self.authority_identity = authority_identity.map(|s| s.to_string());
        self
    }

    pub fn with_credential_name(&mut self, credential_name: Option<&String>) -> &mut Self {
        self.credential_name = credential_name.map(|s| s.to_string());
        self
    }

    pub fn use_default_trust_context(&mut self, use_default_trust_context: bool) -> &mut Self {
        self.use_default_trust_context = use_default_trust_context;
        self
    }

    pub fn build(&self) -> Option<TrustContextConfig> {
        self.trust_context
            .clone()
            .or_else(|| self.get_from_project_path(self.project_path.as_ref()?))
            .or_else(|| self.get_from_project_name())
            .or_else(|| self.get_from_authority_identity())
            .or_else(|| self.get_from_credential())
            .or_else(|| self.get_from_default_trust_context())
            .or_else(|| self.get_from_default_project())
    }

    fn get_from_project_path(&self, path: &PathBuf) -> Option<TrustContextConfig> {
        let s = std::fs::read_to_string(path)
            .into_diagnostic()
            .context("Failed to read project file")
            .ok()?;
        let proj_info = serde_json::from_str::<ProjectConfigCompact>(&s)
            .into_diagnostic()
            .context("Failed to parse project info")
            .ok()?;
        let proj: Project = (&proj_info).into();
        proj.try_into().ok()
    }

    fn get_from_project_name(&self) -> Option<TrustContextConfig> {
        let project = self.cli_state.projects.get(self.project.as_ref()?).ok()?;
        project.config().clone().try_into().ok()
    }

    fn get_from_authority_identity(&self) -> Option<TrustContextConfig> {
        let authority_identity = self.authority_identity.clone();
        let credential = match &self.credential_name {
            Some(c) => Some(self.cli_state.credentials.get(c).ok()?),
            None => None,
        };

        TrustContextConfig::from_authority_identity(&authority_identity?, credential).ok()
    }

    fn get_from_credential(&self) -> Option<TrustContextConfig> {
        let cred_name = self.credential_name.clone()?;
        let cred_state = self.cli_state.credentials.get(cred_name).ok()?;

        cred_state.try_into().ok()
    }

    fn get_from_default_trust_context(&self) -> Option<TrustContextConfig> {
        if !self.use_default_trust_context {
            return None;
        }

        let tc = self
            .cli_state
            .trust_contexts
            .default()
            .ok()?
            .config()
            .clone();
        Some(tc)
    }

    fn get_from_default_project(&self) -> Option<TrustContextConfig> {
        let proj = self.cli_state.projects.default().ok()?;
        self.get_from_project_path(proj.path())
    }
}