use std::sync::Arc;
use std::time::Duration;
use crate::models::SecretRestrictions;
use crate::observer::DataTransferObserver;
use crate::utils::hashing;
#[derive(Default, Clone)]
pub struct SecretSendOptions {
pub observer: Option<Arc<dyn DataTransferObserver>>,
pub chunk_size: Option<usize>,
pub timeout: Option<Duration>,
pub user_agent: Option<String>,
pub restrictions: Option<SecretRestrictions>,
}
impl SecretSendOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_observer(mut self, observer: Arc<dyn DataTransferObserver>) -> Self {
self.observer = Some(observer);
self
}
pub fn with_chunk_size(mut self, size: usize) -> Self {
self.chunk_size = Some(size);
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn with_user_agent(mut self, user_agent: String) -> Self {
self.user_agent = Some(user_agent);
self
}
pub fn with_restrictions(mut self, restrictions: SecretRestrictions) -> Self {
self.restrictions = Some(restrictions);
self
}
}
#[derive(Default, Clone)]
pub struct SecretReceiveOptions {
pub observer: Option<Arc<dyn DataTransferObserver>>,
pub timeout: Option<Duration>,
pub user_agent: Option<String>,
pub passphrase_hash: Option<String>,
}
impl SecretReceiveOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn with_user_agent(mut self, user_agent: String) -> Self {
self.user_agent = Some(user_agent);
self
}
pub fn with_observer(mut self, observer: Arc<dyn DataTransferObserver>) -> Self {
self.observer = Some(observer);
self
}
pub fn with_passphrase(mut self, passphrase: &[u8]) -> Self {
if passphrase.is_empty() {
return self;
}
let hash = hashing::sha256_hex_from_bytes(passphrase);
self.passphrase_hash = Some(hash);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_secret_receive_options_with_passphrase() {
let opts = SecretReceiveOptions::new().with_passphrase(b"mypassword");
let hash = opts.passphrase_hash.expect("Passphrase hash should be set");
assert_eq!(hash.len(), 64, "SHA-256 hash should be 64 characters long");
assert!(
hash.chars().all(|c| c.is_ascii_hexdigit()),
"Hash should contain only hex digits"
);
}
#[test]
fn test_secret_receive_options_with_passphrase_empty() {
let opts = SecretReceiveOptions::new().with_passphrase(b"");
assert!(
opts.passphrase_hash.is_none(),
"Empty passphrase should be ignored"
);
}
#[test]
fn test_secret_receive_options_default_values() {
let opts = SecretReceiveOptions::new();
assert!(opts.observer.is_none(), "Default observer should be None");
assert!(opts.timeout.is_none(), "Default timeout should be None");
assert!(
opts.user_agent.is_none(),
"Default user agent should be None"
);
assert!(
opts.passphrase_hash.is_none(),
"Default passphrase hash should be None"
);
}
#[test]
fn test_secret_receive_options_builder_pattern() {
let opts = SecretReceiveOptions::default()
.with_timeout(Duration::from_secs(120))
.with_user_agent("BuilderTest/1.0".to_string())
.with_passphrase(b"builder_test");
assert_eq!(
opts.timeout,
Some(Duration::from_secs(120)),
"Builder pattern should set timeout"
);
assert_eq!(
opts.user_agent,
Some("BuilderTest/1.0".to_string()),
"Builder pattern should set user agent"
);
assert!(
opts.passphrase_hash.is_some(),
"Builder pattern should set passphrase hash"
);
}
}