use std::fmt;
use std::hash::Hash;
use derive_more::{AsRef, From, Into};
use mti::prelude::*;
use crate::errors::ErnError;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(AsRef, From, Into, Eq, Debug, PartialEq, Clone, Hash, Default, PartialOrd)]
pub struct SHA1Name {
name: MagicTypeId,
}
impl SHA1Name {
pub fn name(&self) -> &MagicTypeId {
&self.name
}
pub fn as_str(&self) -> &str {
&self.name
}
pub fn new(value: String) -> Result<Self, ErnError> {
if value.is_empty() {
return Err(ErnError::ParseFailure(
"SHA1Name",
"cannot be empty".to_string(),
));
}
if value.len() > 1024 {
return Err(ErnError::ParseFailure(
"SHA1Name",
format!(
"length exceeds maximum of 1024 characters (got {})",
value.len()
),
));
}
Ok(SHA1Name {
name: value.create_type_id::<V5>(),
})
}
}
impl fmt::Display for SHA1Name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let id = &self.name;
write!(f, "{id}")
}
}
impl std::str::FromStr for SHA1Name {
type Err = ErnError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.is_empty() {
return Err(ErnError::ParseFailure(
"SHA1Name",
"cannot be empty".to_string(),
));
}
if s.len() > 1024 {
return Err(ErnError::ParseFailure(
"SHA1Name",
format!(
"length exceeds maximum of 1024 characters (got {})",
s.len()
),
));
}
Ok(SHA1Name {
name: s.create_type_id::<V5>(),
})
}
}
#[cfg(feature = "serde")]
impl Serialize for SHA1Name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.name.as_ref())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for SHA1Name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
SHA1Name::new(s).map_err(serde::de::Error::custom)
}
}
use crate::Part;
use crate::traits::ErnComponent;
impl ErnComponent for SHA1Name {
fn prefix() -> &'static str {
""
}
type NextState = Part;
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn test_sha1name_deterministic() {
let name1 = SHA1Name::new("test_content".to_string()).unwrap();
let name2 = SHA1Name::new("test_content".to_string()).unwrap();
assert_eq!(name1, name2);
assert_eq!(name1.to_string(), name2.to_string());
}
#[test]
fn test_sha1name_different_inputs() {
let name1 = SHA1Name::new("completely_different_content_1".to_string()).unwrap();
let name2 = SHA1Name::new("entirely_unique_content_2".to_string()).unwrap();
assert_ne!(name1, name2);
assert_ne!(name1.to_string(), name2.to_string());
}
#[test]
fn test_sha1name_from_str() {
let name1 = SHA1Name::new("test_content".to_string()).unwrap();
let name2 = SHA1Name::from_str("test_content").unwrap();
assert_eq!(name1, name2);
assert_eq!(name1.to_string(), name2.to_string());
}
#[test]
fn test_sha1name_display() {
let name = SHA1Name::new("test_content".to_string()).unwrap();
let display = name.to_string();
assert!(!display.is_empty());
}
#[test]
fn test_sha1name_validation_empty() {
let result = SHA1Name::new("".to_string());
assert!(result.is_err());
match result {
Err(ErnError::ParseFailure(component, msg)) => {
assert_eq!(component, "SHA1Name");
assert!(msg.contains("empty"));
}
_ => panic!("Expected ParseFailure error for empty SHA1Name"),
}
}
#[test]
fn test_sha1name_validation_too_long() {
let long_value = "a".repeat(1025);
let result = SHA1Name::new(long_value);
assert!(result.is_err());
match result {
Err(ErnError::ParseFailure(component, msg)) => {
assert_eq!(component, "SHA1Name");
assert!(msg.contains("length exceeds maximum"));
}
_ => panic!("Expected ParseFailure error for too long SHA1Name"),
}
}
#[test]
fn test_sha1name_from_str_validation() {
let result = SHA1Name::from_str("");
assert!(result.is_err());
match result {
Err(ErnError::ParseFailure(component, msg)) => {
assert_eq!(component, "SHA1Name");
assert!(msg.contains("empty"));
}
_ => panic!("Expected ParseFailure error for empty SHA1Name from_str"),
}
}
}