@@ -8,50 +8,43 @@ use crate::{
8
8
} ;
9
9
10
10
/// Catalyst Signed Document Builder.
11
- #[ derive( Debug , Default , Clone ) ]
12
- pub struct Builder {
13
- /// Document Metadata
14
- metadata : Option < Metadata > ,
15
- /// Document Content
16
- content : Option < Vec < u8 > > ,
17
- /// Signatures
18
- signatures : Signatures ,
11
+ #[ derive( Debug ) ]
12
+ pub struct Builder ( InnerCatalystSignedDocument ) ;
13
+
14
+ impl Default for Builder {
15
+ fn default ( ) -> Self {
16
+ Self :: new ( )
17
+ }
19
18
}
20
19
21
20
impl Builder {
22
21
/// Start building a signed document
23
22
#[ must_use]
24
23
pub fn new ( ) -> Self {
25
- Self :: default ( )
26
- }
27
-
28
- /// Set document metadata
29
- #[ must_use]
30
- pub fn with_metadata ( mut self , metadata : Metadata ) -> Self {
31
- self . metadata = Some ( metadata) ;
32
- self
24
+ let report = ProblemReport :: new ( PROBLEM_REPORT_CTX ) ;
25
+ Self ( InnerCatalystSignedDocument {
26
+ report,
27
+ metadata : Metadata :: default ( ) ,
28
+ content : Content :: default ( ) ,
29
+ signatures : Signatures :: default ( ) ,
30
+ } )
33
31
}
34
32
35
33
/// Set document metadata in JSON format
34
+ /// Collect problem report if some fields are missing.
36
35
///
37
36
/// # Errors
38
- /// - Fails if it is invalid metadata JSON object.
37
+ /// - Fails if it is invalid metadata fields JSON object.
39
38
pub fn with_json_metadata ( mut self , json : serde_json:: Value ) -> anyhow:: Result < Self > {
40
- self . metadata = Some ( serde_json:: from_value ( json) ?) ;
39
+ let metadata = serde_json:: from_value ( json) ?;
40
+ self . 0 . metadata = Metadata :: from_metadata_fields ( metadata, & self . 0 . report ) ;
41
41
Ok ( self )
42
42
}
43
43
44
44
/// Set decoded (original) document content bytes
45
45
#[ must_use]
46
46
pub fn with_decoded_content ( mut self , content : Vec < u8 > ) -> Self {
47
- self . content = Some ( content) ;
48
- self
49
- }
50
-
51
- /// Set document signatures
52
- #[ must_use]
53
- pub fn with_signatures ( mut self , signatures : Signatures ) -> Self {
54
- self . signatures = signatures;
47
+ self . 0 . content = Content :: from_decoded ( content) ;
55
48
self
56
49
}
57
50
@@ -62,59 +55,40 @@ impl Builder {
62
55
/// Fails if a `CatalystSignedDocument` cannot be created due to missing metadata or
63
56
/// content, due to malformed data, or when the signed document cannot be
64
57
/// converted into `coset::CoseSign`.
65
- pub fn add_signature ( self , sk : SecretKey , kid : IdUri ) -> anyhow:: Result < Self > {
58
+ pub fn add_signature ( mut self , sk : SecretKey , kid : IdUri ) -> anyhow:: Result < Self > {
66
59
let cose_sign = self
67
- . clone ( )
68
- . build ( )
69
- . map_err ( |e| anyhow:: anyhow!( "Failed to sign: {e}" ) ) ?
60
+ . 0
70
61
. as_cose_sign ( )
71
62
. map_err ( |e| anyhow:: anyhow!( "Failed to sign: {e}" ) ) ?;
72
- let Self {
73
- metadata : Some ( metadata) ,
74
- content : Some ( content) ,
75
- mut signatures,
76
- } = self
77
- else {
78
- anyhow:: bail!( "Metadata and Content are needed for signing" ) ;
79
- } ;
63
+
80
64
let sk = ed25519_dalek:: SigningKey :: from_bytes ( & sk) ;
81
- let protected_header = coset:: HeaderBuilder :: new ( )
82
- . key_id ( kid. to_string ( ) . into_bytes ( ) )
83
- . algorithm ( metadata. algorithm ( ) ?. into ( ) ) ;
65
+ let protected_header = coset:: HeaderBuilder :: new ( ) . key_id ( kid. to_string ( ) . into_bytes ( ) ) ;
66
+
84
67
let mut signature = coset:: CoseSignatureBuilder :: new ( )
85
68
. protected ( protected_header. build ( ) )
86
69
. build ( ) ;
87
70
let data_to_sign = cose_sign. tbs_data ( & [ ] , & signature) ;
88
71
signature. signature = sk. sign ( & data_to_sign) . to_vec ( ) ;
89
- signatures. push ( kid, signature) ;
90
- Ok ( Self :: new ( )
91
- . with_decoded_content ( content)
92
- . with_metadata ( metadata)
93
- . with_signatures ( signatures) )
72
+ self . 0 . signatures . push ( kid, signature) ;
73
+
74
+ Ok ( self )
94
75
}
95
76
96
- /// Build a signed document
97
- ///
98
- /// ## Errors
99
- ///
100
- /// Fails if any of the fields are missing.
101
- pub fn build ( self ) -> anyhow:: Result < CatalystSignedDocument > {
102
- let Some ( metadata) = self . metadata else {
103
- anyhow:: bail!( "Failed to build Catalyst Signed Document, missing metadata" ) ;
104
- } ;
105
- let Some ( content) = self . content else {
106
- anyhow:: bail!( "Failed to build Catalyst Signed Document, missing document's content" ) ;
107
- } ;
108
- let signatures = self . signatures ;
109
- let content = Content :: from_decoded ( content, metadata. content_type ( ) ?) ?;
77
+ /// Build a signed document with the collected error report.
78
+ /// Could provide an invalid document.
79
+ #[ must_use]
80
+ pub fn build ( self ) -> CatalystSignedDocument {
81
+ self . 0 . into ( )
82
+ }
83
+ }
110
84
111
- let empty_report = ProblemReport :: new ( PROBLEM_REPORT_CTX ) ;
112
- Ok ( InnerCatalystSignedDocument {
113
- metadata ,
114
- content ,
115
- signatures ,
116
- report : empty_report ,
117
- }
118
- . into ( ) )
85
+ impl From < & CatalystSignedDocument > for Builder {
86
+ fn from ( value : & CatalystSignedDocument ) -> Self {
87
+ Self ( InnerCatalystSignedDocument {
88
+ metadata : value . inner . metadata . clone ( ) ,
89
+ content : value . inner . content . clone ( ) ,
90
+ signatures : value . inner . signatures . clone ( ) ,
91
+ report : value . inner . report . clone ( ) ,
92
+ } )
119
93
}
120
94
}
0 commit comments