dubp_documents/traits/
text.rs1use crate::*;
19
20#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
21pub enum TextDocumentFormat<D: TextDocument> {
23 Complete(D),
25 Compact(D::CompactTextDocument_),
27}
28
29impl<D: TextDocument> TextDocumentFormat<D> {
30 pub fn to_compact_document(&self) -> Cow<D::CompactTextDocument_> {
32 match *self {
33 TextDocumentFormat::Complete(ref doc) => doc.to_compact_document(),
34 TextDocumentFormat::Compact(ref compact_doc) => Cow::Borrowed(compact_doc),
35 }
36 }
37}
38
39pub trait CompactTextDocument: Sized + Clone + PartialEq {
41 fn as_compact_text(&self) -> String;
47}
48
49impl<D: TextDocument> CompactTextDocument for TextDocumentFormat<D> {
50 fn as_compact_text(&self) -> String {
51 match *self {
52 TextDocumentFormat::Complete(ref doc) => doc.generate_compact_text(),
53 TextDocumentFormat::Compact(ref doc) => doc.as_compact_text(),
54 }
55 }
56}
57
58pub trait TextDocument: Document {
60 type CompactTextDocument_: CompactTextDocument;
62
63 fn as_text(&self) -> &str;
65
66 fn as_text_with_signatures(&self) -> String {
68 let mut text = self.as_text().to_string();
69
70 for sig in self.signatures() {
71 text.push_str(&sig.to_base64());
72 text.push('\n');
73 }
74 text.pop(); text
77 }
78
79 fn to_compact_document(&self) -> Cow<Self::CompactTextDocument_>;
83
84 fn generate_compact_text(&self) -> String {
90 self.to_compact_document().as_compact_text()
91 }
92}
93
94pub type StringAndSmallVec1<T> = (String, SmallVec<[T; 1]>);
95
96pub trait TextDocumentBuilder {
98 type Document: Document;
100 type Signator: Signator<PublicKey = <Self::Document as Document>::PublicKey>;
102
103 fn generate_text(&self) -> String;
108
109 fn build_signed_text(
116 &self,
117 signators: Vec<Self::Signator>,
118 ) -> StringAndSmallVec1<<<Self::Document as Document>::PublicKey as PublicKey>::Signature> {
119 let text = self.generate_text();
120
121 let signatures: SmallVec<_> = {
122 let text_bytes = text.as_bytes();
123 signators
124 .iter()
125 .map(|signator| signator.sign(text_bytes))
126 .collect()
127 };
128
129 (text, signatures)
130 }
131
132 fn build_with_text_and_sigs(
134 self,
135 text: String,
136 signatures: SmallVec<
137 [<<Self::Document as Document>::PublicKey as PublicKey>::Signature; 1],
138 >,
139 ) -> Self::Document;
140}
141
142impl<T> DocumentBuilder for T
143where
144 T: TextDocumentBuilder,
145{
146 type Document = <Self as TextDocumentBuilder>::Document;
147 type Signator = <Self as TextDocumentBuilder>::Signator;
148
149 fn build_and_sign(self, signators: Vec<Self::Signator>) -> Self::Document {
150 let (text, signatures) = self.build_signed_text(signators);
151 self.build_with_text_and_sigs(text, signatures)
152 }
153
154 fn build_with_signature(
155 self,
156 signatures: SmallVec<
157 [<<Self::Document as Document>::PublicKey as PublicKey>::Signature; 1],
158 >,
159 ) -> Self::Document {
160 let text = self.generate_text();
161 self.build_with_text_and_sigs(text, signatures)
162 }
163}