1mod identity;
7mod repository;
8
9pub use identity::{Identity, PublicKey, Signature};
10pub use repository::{Repository, RepositoryId};
11
12use commonware_utils::hex;
13
14pub const NAMESPACE: &[u8] = b"_GUTS";
16
17pub const EPOCH: u64 = 0;
22
23pub const EPOCH_LENGTH: u64 = u64::MAX;
28
29#[repr(u8)]
31pub enum MessageKind {
32 RepoUpdate = 0,
34 PullRequest = 1,
36 Issue = 2,
38}
39
40impl MessageKind {
41 pub fn from_u8(value: u8) -> Option<Self> {
43 match value {
44 0 => Some(Self::RepoUpdate),
45 1 => Some(Self::PullRequest),
46 2 => Some(Self::Issue),
47 _ => None,
48 }
49 }
50
51 pub fn to_hex(&self) -> String {
53 match self {
54 Self::RepoUpdate => hex(&[0]),
55 Self::PullRequest => hex(&[1]),
56 Self::Issue => hex(&[2]),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_message_kind_roundtrip() {
67 assert!(matches!(
68 MessageKind::from_u8(0),
69 Some(MessageKind::RepoUpdate)
70 ));
71 assert!(matches!(
72 MessageKind::from_u8(1),
73 Some(MessageKind::PullRequest)
74 ));
75 assert!(matches!(MessageKind::from_u8(2), Some(MessageKind::Issue)));
76 assert!(MessageKind::from_u8(255).is_none());
77 }
78
79 #[test]
80 fn test_message_kind_all_invalid_values() {
81 for i in 3..=255u8 {
83 assert!(
84 MessageKind::from_u8(i).is_none(),
85 "Expected None for value {}",
86 i
87 );
88 }
89 }
90
91 #[test]
92 fn test_message_kind_to_hex() {
93 assert_eq!(MessageKind::RepoUpdate.to_hex(), hex(&[0]));
94 assert_eq!(MessageKind::PullRequest.to_hex(), hex(&[1]));
95 assert_eq!(MessageKind::Issue.to_hex(), hex(&[2]));
96 }
97
98 #[test]
99 fn test_namespace_constant() {
100 assert_eq!(NAMESPACE, b"_GUTS");
101 assert_eq!(NAMESPACE.len(), 5);
102 }
103
104 #[test]
105 fn test_epoch_constants() {
106 assert_eq!(EPOCH, 0);
107 assert_eq!(EPOCH_LENGTH, u64::MAX);
108 }
109}