Skip to content

Commit 3a6795d

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 3a6795d

File tree

4 files changed

+94
-23
lines changed

4 files changed

+94
-23
lines changed

.config/dictionaries/project.dic

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ upnp
259259
ureq
260260
userid
261261
utimensat
262+
uuidv4
263+
uuidv7
262264
UTXO
263265
vitss
264266
Vkey

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

0 commit comments

Comments
 (0)