use bstr::BString;
use crate::helper;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Outcome {
pub identity: gix_sec::identity::Account,
pub next: helper::NextAction,
}
pub type Result = std::result::Result<Option<Outcome>, Error>;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
UrlParse(#[from] gix_url::parse::Error),
#[error("Either 'url' field or both 'protocol' and 'host' fields must be provided")]
UrlMissing,
#[error(transparent)]
ContextDecode(#[from] context::decode::Error),
#[error(transparent)]
InvokeHelper(#[from] helper::Error),
#[error("Could not obtain identity for context: {}", { let mut buf = Vec::<u8>::new(); context.write_to(&mut buf).ok(); String::from_utf8_lossy(&buf).into_owned() })]
IdentityMissing { context: Context },
#[error("The handler asked to stop trying to obtain credentials")]
Quit,
#[error("Couldn't obtain {prompt}")]
Prompt { prompt: String, source: gix_prompt::Error },
}
#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct Context {
pub protocol: Option<String>,
pub host: Option<String>,
pub path: Option<BString>,
pub username: Option<String>,
pub password: Option<String>,
pub oauth_refresh_token: Option<String>,
pub password_expiry_utc: Option<gix_date::SecondsSinceUnixEpoch>,
pub url: Option<BString>,
pub quit: Option<bool>,
}
#[allow(clippy::result_large_err)]
pub fn helper_outcome_to_result(outcome: Option<helper::Outcome>, action: helper::Action) -> Result {
match (action, outcome) {
(helper::Action::Get(ctx), None) => Err(Error::IdentityMissing {
context: ctx.redacted(),
}),
(helper::Action::Get(ctx), Some(mut outcome)) => match outcome.consume_identity() {
Some(identity) => Ok(Some(Outcome {
identity,
next: outcome.next,
})),
None => Err(if outcome.quit {
Error::Quit
} else {
Error::IdentityMissing {
context: ctx.redacted(),
}
}),
},
(helper::Action::Store(_) | helper::Action::Erase(_), _ignore) => Ok(None),
}
}
pub mod context;