Skip to content

Commit de39c91

Browse files
committed
wip(rust/signed_doc): add basic structure for catalyst signed document API
* refactor code from mk_signed_doc example into src/lib.rs
1 parent a7680af commit de39c91

File tree

3 files changed

+93
-23
lines changed

3 files changed

+93
-23
lines changed

rust/signed_doc/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ license.workspace = true
1111
workspace = true
1212

1313
[dependencies]
14-
15-
[dev-dependencies]
16-
clap = { version = "4.5.19", features = ["derive", "env"] }
1714
anyhow = "1.0.89"
1815
serde = { version = "1.0.210", features = ["derive"] }
1916
serde_json = "1.0"
@@ -22,3 +19,6 @@ coset = "0.3.7"
2219
brotli = "7.0.0"
2320
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
2421
uuid = { version = "1.10.0", features = ["v4", "v7", "serde"] }
22+
23+
[dev-dependencies]
24+
clap = { version = "4.5.19", features = ["derive", "env"] }

rust/signed_doc/examples/mk_signed_doc.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use ed25519_dalek::{
1414
ed25519::signature::Signer,
1515
pkcs8::{DecodePrivateKey, DecodePublicKey},
1616
};
17+
use signed_doc::{DocumentRef, Metadata};
1718

1819
fn main() {
1920
if let Err(err) = Cli::parse().exec() {
@@ -60,26 +61,6 @@ const CONTENT_ENCODING_KEY: &str = "content encoding";
6061
const CONTENT_ENCODING_VALUE: &str = "br";
6162
const UUID_CBOR_TAG: u64 = 37;
6263

63-
#[derive(Debug, serde::Deserialize)]
64-
struct Metadata {
65-
r#type: uuid::Uuid,
66-
id: uuid::Uuid,
67-
ver: uuid::Uuid,
68-
r#ref: Option<DocumentRef>,
69-
template: Option<DocumentRef>,
70-
reply: Option<DocumentRef>,
71-
section: Option<String>,
72-
}
73-
74-
#[derive(Debug, serde::Deserialize)]
75-
#[serde(untagged)]
76-
enum DocumentRef {
77-
/// Reference to the latest document
78-
Latest { id: uuid::Uuid },
79-
/// Reference to the specific document version
80-
WithVer { id: uuid::Uuid, ver: uuid::Uuid },
81-
}
82-
8364
fn encode_cbor_uuid(uuid: &uuid::Uuid) -> coset::cbor::Value {
8465
coset::cbor::Value::Tag(
8566
UUID_CBOR_TAG,

rust/signed_doc/src/lib.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,90 @@
11
//! Catalyst documents signing crate
2+
use std::sync::Arc;
3+
use std::convert::TryFrom;
4+
5+
/// Keep all the contents private.
6+
/// Better even to use a structure like this. Wrapping in an Arc means we don't have to
7+
/// manage the Arc anywhere else. These are likely to be large, best to have the Arc be
8+
/// non-optional.
9+
pub struct CatalystSignedDocument {
10+
/// Catalyst Signed Document metadata, raw doc, with content errors.
11+
inner: Arc<InnerCatalystSignedDocument>,
12+
}
13+
14+
/// Inner type that holds the Catalyst Signed Document with parsing errors.
15+
struct InnerCatalystSignedDocument {
16+
/// Document Metadata
17+
_metadata: Metadata,
18+
/// Raw payload
19+
_raw_doc: Vec<u8>,
20+
/// Content Errors found when parsing the Document
21+
content_errors: Vec<String>,
22+
}
23+
24+
/// Document Metadata.
25+
#[derive(Debug, serde::Deserialize)]
26+
pub struct Metadata {
27+
/// Document Type `UUIDv7`.
28+
pub r#type: uuid::Uuid,
29+
/// Document ID `UUIDv7`.
30+
pub id: uuid::Uuid,
31+
/// Document Version `UUIDv7`.
32+
pub ver: uuid::Uuid,
33+
/// Reference to the latest document.
34+
pub r#ref: Option<DocumentRef>,
35+
/// Reference to the document template.
36+
pub template: Option<DocumentRef>,
37+
/// Reference to the document reply.
38+
pub reply: Option<DocumentRef>,
39+
/// Reference to the document section.
40+
pub section: Option<String>,
41+
}
42+
43+
/// Reference to a Document.
44+
#[derive(Debug, serde::Deserialize)]
45+
#[serde(untagged)]
46+
pub enum DocumentRef {
47+
/// Reference to the latest document
48+
Latest {
49+
/// Document ID UUID
50+
id: uuid::Uuid,
51+
},
52+
/// Reference to the specific document version
53+
WithVer {
54+
/// Document ID UUID
55+
id: uuid::Uuid,
56+
/// Document Version UUID
57+
ver: uuid::Uuid,
58+
},
59+
}
60+
61+
// Do this instead of `new` if we are converting a single parameter into a struct/type we
62+
// should use either `From` or `TryFrom` and reserve `new` for cases where we need
63+
// multiple parameters to actually create the type. This is much more elegant to use this
64+
// way, in code.
65+
impl TryFrom<Vec<u8> for CatalystSignedDocument {
66+
type Error = &'static str;
67+
68+
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
69+
todo!();
70+
}
71+
}
72+
73+
impl CatalystSignedDocument {
74+
/// Invalid Doc Type UUID
75+
const INVALID_UUID: uuid::Uuid = uuid::Uuid::from_bytes([0u8; 16]);
76+
77+
// A bunch of getters to access the contents, or reason through the document, such as.
78+
79+
/// Are there any validation errors (as opposed to structural errors.
80+
#[must_use]
81+
pub fn has_error(&self) -> bool {
82+
!self.inner.content_errors.is_empty()
83+
}
84+
85+
/// Return Document Type UUID.
86+
#[must_use]
87+
pub fn doc_type(&self) -> uuid::Uuid {
88+
INVALID_UUID
89+
} // Can compare it against INVALID_DOC_TYPE to see if its valid or not.
90+
}

0 commit comments

Comments
 (0)