cloud_terrastodon_credentials 0.34.0

Helpers for getting Azure PAT and stuff for Cloud Terrastodon
use crate::AuthBearerExt;
#[cfg(windows)]
use crate::read_azure_devops_pat_from_credential_manager;
use reqwest::header::HeaderValue;
use std::ops::Deref;

#[derive(Debug)]
pub struct AzureDevOpsPersonalAccessToken {
    inner: String,
}
impl AzureDevOpsPersonalAccessToken {
    pub fn new(inner: impl Into<String>) -> Self {
        Self {
            inner: inner.into(),
        }
    }
}
impl AsRef<str> for AzureDevOpsPersonalAccessToken {
    fn as_ref(&self) -> &str {
        &self.inner
    }
}
impl Deref for AzureDevOpsPersonalAccessToken {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}
impl std::fmt::Display for AzureDevOpsPersonalAccessToken {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.inner)
    }
}
impl<'de> serde::Deserialize<'de> for AzureDevOpsPersonalAccessToken {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let value = <String as serde::Deserialize>::deserialize(deserializer)?;
        Ok(Self::new(value))
    }
}
impl From<AzureDevOpsPersonalAccessToken> for HeaderValue {
    fn from(value: AzureDevOpsPersonalAccessToken) -> Self {
        value.as_authorization_header_value()
    }
}

pub async fn get_azure_devops_personal_access_token_from_credential_manager()
-> eyre::Result<AzureDevOpsPersonalAccessToken> {
    #[cfg(windows)]
    return read_azure_devops_pat_from_credential_manager();
    #[cfg(not(windows))]
    return Ok(AzureDevOpsPersonalAccessToken::new(std::env::var(
        "AZDO_PERSONAL_ACCESS_TOKEN",
    )?));
}

#[cfg(test)]
mod test {
    use crate::get_azure_devops_personal_access_token_from_credential_manager;

    #[tokio::test]
    pub async fn non_empty() -> eyre::Result<()> {
        let credential = get_azure_devops_personal_access_token_from_credential_manager()
            .await
            .ok();
        if let Some(credential) = credential {
            assert!(!credential.is_empty());
        } else {
            println!("No credential found, skipping test");
        }
        Ok(())
    }
}