#[derive(Debug, Clone, uniffi::Object)]
pub struct UserAgent(pub String);
impl std::fmt::Display for UserAgent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)?;
Ok(())
}
}
#[derive(Debug, Clone, uniffi::Object)]
pub struct UserAgentBuilder {
segments: Vec<String>,
}
#[uniffi::export]
impl UserAgentBuilder {
#[uniffi::constructor]
#[must_use]
pub const fn new() -> Self {
Self {
segments: Vec::new(),
}
}
#[must_use]
pub fn with_segment(&self, name: &str, version: &str) -> Self {
let mut next = self.clone();
next.segments.push(format!("{name}/{version}"));
next
}
#[must_use]
pub fn with_walletkit_segment(&self) -> Self {
let mut next = self.clone();
let crate_version = env!("CARGO_PKG_VERSION");
next.segments
.push(format!("walletkit-core/{crate_version}"));
next
}
#[must_use]
pub fn build(&self) -> UserAgent {
UserAgent(self.segments.join(" "))
}
}
impl Default for UserAgentBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_case::test_case;
#[test_case(
&UserAgentBuilder::new().with_walletkit_segment(),
concat!("walletkit-core/", env!("CARGO_PKG_VERSION"));
"walletkit_only"
)]
#[test_case(
&UserAgentBuilder::new()
.with_segment("WorldApp", "1.0")
.with_walletkit_segment(),
concat!("WorldApp/1.0 walletkit-core/", env!("CARGO_PKG_VERSION"));
"world_app_then_walletkit"
)]
#[test_case(
&UserAgentBuilder::new()
.with_segment("WorldApp", "2.1")
.with_walletkit_segment()
.with_segment("iOS", "17.0"),
concat!("WorldApp/2.1 walletkit-core/", env!("CARGO_PKG_VERSION"), " iOS/17.0");
"native_style_world_walletkit_os"
)]
#[test_case(
&UserAgentBuilder::new()
.with_walletkit_segment()
.with_segment("CLI", "1.2.3"),
concat!("walletkit-core/", env!("CARGO_PKG_VERSION"), " CLI/1.2.3");
"walletkit_then_cli"
)]
fn user_agent_builder_expected(builder: &UserAgentBuilder, expected: &'static str) {
assert_eq!(builder.build().to_string(), expected);
}
}