use std::fmt::Display;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::hash::{Hash, HashError};
use crate::operation::OperationId;
use crate::Validate;
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct DocumentId(OperationId);
impl DocumentId {
pub fn new(id: OperationId) -> Self {
Self(id)
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl Display for DocumentId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.as_hash().short_str())
}
}
impl Validate for DocumentId {
type Error = HashError;
fn validate(&self) -> Result<(), Self::Error> {
self.0.validate()
}
}
impl From<Hash> for DocumentId {
fn from(hash: Hash) -> Self {
Self::new(hash.into())
}
}
impl FromStr for DocumentId {
type Err = HashError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new(s.parse::<OperationId>()?))
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use crate::hash::Hash;
use crate::operation::OperationId;
use crate::test_utils::fixtures::random_hash;
use super::DocumentId;
#[rstest]
fn conversion(#[from(random_hash)] hash: Hash) {
let hash_str = "0020cfb0fa37f36d082faad3886a9ffbcc2813b7afe90f0609a556d425f1a76ec805";
let document_id: DocumentId = hash_str.parse().unwrap();
assert_eq!(
document_id,
DocumentId::new(hash_str.parse::<OperationId>().unwrap())
);
assert_eq!(document_id.as_str(), hash_str);
let document_id = DocumentId::from(hash.clone());
assert_eq!(document_id, DocumentId::new(hash.into()));
assert!("This is not a hash".parse::<DocumentId>().is_err());
}
}