1- //! Signed Document Locator
1+ //! Signed Document Locator for `CIDv0`, Base32 `CIDv1`, and Base36 `CIDv1`
22//!
3- //! `hex` Encoded Document Locator.
3+ //! Reference: <https://docs.ipfs.tech/concepts/content-addressing>
4+
5+ // cspell: words cidv
6+
7+ use std:: sync:: LazyLock ;
48
59use poem_openapi:: {
6- registry:: { MetaSchema , MetaSchemaRef } ,
10+ registry:: { MetaExternalDocument , MetaSchema , MetaSchemaRef } ,
711 types:: { Example , ParseError , ParseFromJSON , ParseFromParameter , ParseResult , ToJSON , Type } ,
812} ;
13+ use regex:: Regex ;
914use serde_json:: Value ;
1015
1116use crate :: service:: common:: types:: string_types:: impl_string_types;
1217
1318/// Title.
1419const TITLE : & str = "Signed Document Locator" ;
1520/// Description.
16- const DESCRIPTION : & str = "Document Locator, encoded in hex string" ;
17- /// Example.
18- const EXAMPLE : & str = "0x" ;
21+ const DESCRIPTION : & str = "Document Locator in the IPFS CID formats" ;
22+ // cspell: disable
23+ /// Example for `CIDv1` Base32.
24+ const EXAMPLE_CID_V1_B32 : & str = "bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku" ;
25+ /// Example for `CIDv1` Base36.
26+ #[ allow( dead_code) ]
27+ const EXAMPLE_CID_V1_B36 : & str = "k2k4r8jl0yz8qjgqbmc2cdu5hkqek5rj6flgnlkyywynci20j0iuyfuj" ;
28+ /// Example for `CIDv0`.
29+ #[ allow( dead_code) ]
30+ const EXAMPLE_CID_V0 : & str = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR" ;
31+ // cspell: enable
1932/// Validation Regex Pattern
20- const PATTERN : & str = "^0x([0-9a-f]{2})*$" ;
33+ const PATTERN : & str = r"^(Qm[1-9A-HJ-NP-Za-km-z]{44})|(b[a-z2-7]{58})|([kK][0-9a-zA-Z]+)$" ;
34+
35+ /// Regular expression to validate cidv0, cidv1b32, and cidv1b36.
36+ #[ allow( clippy:: unwrap_used) ]
37+ static REGEX : LazyLock < Regex > = LazyLock :: new ( || Regex :: new ( PATTERN ) . unwrap ( ) ) ;
2138
2239/// Because ALL the constraints are defined above, we do not ever need to define them in
2340/// the API. BUT we do need to make a validator.
2441/// This helps enforce uniform validation.
2542fn is_valid ( value : & str ) -> bool {
26- value
27- . strip_prefix ( "0x" )
28- . is_some_and ( |hex| hex:: decode ( hex) . is_ok ( ) )
43+ REGEX . is_match ( value)
2944}
3045
3146impl_string_types ! (
3247 DocumentLocator ,
3348 "string" ,
34- "hex " ,
49+ "cidv0 || cidv1b32 || cidv1b36 " ,
3550 Some ( MetaSchema {
3651 title: Some ( TITLE . to_owned( ) ) ,
3752 description: Some ( DESCRIPTION ) ,
38- example: Some ( EXAMPLE . into( ) ) ,
53+ external_docs: Some ( MetaExternalDocument {
54+ url: "https://docs.ipfs.tech/concepts/content-addressing" . to_owned( ) ,
55+ description: Some ( "Content Identifiers (CIDs) | IPFS Docs" . to_owned( ) ) ,
56+ } ) ,
57+ example: Some ( EXAMPLE_CID_V1_B32 . into( ) ) ,
3958 max_length: Some ( 66 ) ,
4059 min_length: Some ( 2 ) ,
4160 pattern: Some ( PATTERN . to_string( ) ) ,
@@ -46,7 +65,7 @@ impl_string_types!(
4665
4766impl Example for DocumentLocator {
4867 fn example ( ) -> Self {
49- Self ( EXAMPLE . to_owned ( ) )
68+ Self ( EXAMPLE_CID_V1_B32 . to_owned ( ) )
5069 }
5170}
5271
0 commit comments