Skip to content
Clone
b453d5d
73 lines 2.0 KB Rust
use base64::Engine;
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct PowConfig {
pub difficulty: u32,
pub max_difficulty: u32,
pub expires_secs: u64,
pub mac_key: Option<String>,
}
impl Default for PowConfig {
fn default() -> Self {
Self {
difficulty: 16,
max_difficulty: 24,
expires_secs: 60,
mac_key: None,
}
}
}
impl PowConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_difficulty(mut self, difficulty: u32) -> Self {
self.difficulty = difficulty;
self
}
pub fn with_max_difficulty(mut self, max_difficulty: u32) -> Self {
self.max_difficulty = max_difficulty;
self
}
pub fn with_expires_secs(mut self, expires_secs: u64) -> Self {
self.expires_secs = expires_secs;
self
}
pub fn with_mac_key(mut self, mac_key: impl Into<String>) -> Self {
self.mac_key = Some(mac_key.into());
self
}
pub fn validate(&self) -> Result<(), String> {
if self.max_difficulty > 256 {
return Err("pow.max_difficulty must be <= 256".to_string());
}
if self.difficulty > self.max_difficulty {
return Err("pow.difficulty must be <= pow.max_difficulty".to_string());
}
if self.expires_secs == 0 {
return Err("pow.expires_secs must be greater than 0".to_string());
}
match &self.mac_key {
Some(key) => {
let length = base64::engine::general_purpose::STANDARD
.decode(key)
.map(|bytes| bytes.len())
.unwrap_or(0);
if length < 32 {
return Err("pow.mac_key must be base64 of at least 32 bytes".to_string());
}
}
None => return Err("pow.mac_key is required".to_string()),
}
Ok(())
}
}