systemprompt_identifiers/
documents.rs1use crate::error::IdValidationError;
21
22crate::define_id!(DocumentId, uuid);
23crate::define_id!(DocumentFolderId, uuid);
24crate::define_id!(DocumentRevisionId, uuid);
25crate::define_id!(DocumentEditSessionId, uuid);
26crate::define_id!(DocumentCommentId, uuid);
27crate::define_id!(DocumentProposalId, uuid);
28crate::define_id!(ContentHash, checked, validate_content_hash);
29crate::define_id!(DocumentNodeId, checked, |value| {
30 crate::macros::validate_non_empty("DocumentNodeId", value)
31});
32crate::define_id!(DocumentOpId, checked, |value| {
33 crate::macros::validate_non_empty("DocumentOpId", value)
34});
35crate::define_id!(DocumentTemplateId, checked, |value| {
36 crate::macros::validate_non_empty("DocumentTemplateId", value)
37});
38crate::define_id!(DriveDeviceId, checked, |value| {
39 crate::macros::validate_non_empty("DriveDeviceId", value)
40});
41
42const CONTENT_HASH_LEN: usize = 64;
43
44fn validate_content_hash(value: &str) -> Result<(), IdValidationError> {
45 if value.is_empty() {
46 return Err(IdValidationError::empty("ContentHash"));
47 }
48 if value.len() != CONTENT_HASH_LEN {
49 return Err(IdValidationError::invalid(
50 "ContentHash",
51 "must be exactly 64 hex characters",
52 ));
53 }
54 if !value
55 .bytes()
56 .all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
57 {
58 return Err(IdValidationError::invalid(
59 "ContentHash",
60 "must be lowercase hex",
61 ));
62 }
63 Ok(())
64}