heddle_object_model/object/
facet_kind.rs1use std::fmt;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
16pub enum FacetKind {
17 SourceHistory,
20 ConfidentialRuntime,
23 Collaboration,
25 AgentTimeline,
27}
28
29#[derive(Clone, Copy, Debug, PartialEq, Eq)]
34pub struct SourceHistoryLaws {
35 _private: (),
36}
37
38impl FacetKind {
39 pub const ALL: [Self; 4] = [
41 Self::SourceHistory,
42 Self::ConfidentialRuntime,
43 Self::Collaboration,
44 Self::AgentTimeline,
45 ];
46
47 pub const fn as_str(self) -> &'static str {
48 match self {
49 Self::SourceHistory => "source-history",
50 Self::ConfidentialRuntime => "confidential-runtime",
51 Self::Collaboration => "collaboration",
52 Self::AgentTimeline => "agent-timeline",
53 }
54 }
55
56 pub const fn source_history_laws(self) -> Option<SourceHistoryLaws> {
59 match self {
60 Self::SourceHistory => Some(SourceHistoryLaws { _private: () }),
61 Self::ConfidentialRuntime | Self::Collaboration | Self::AgentTimeline => None,
62 }
63 }
64
65 pub const fn may_checkout(self) -> bool {
66 self.source_history_laws().is_some()
67 }
68
69 pub const fn may_land(self) -> bool {
70 self.source_history_laws().is_some()
71 }
72
73 pub const fn git_projection_visits(self) -> bool {
74 self.source_history_laws().is_some()
75 }
76
77 pub const fn require_worktree_materialization(self) -> Result<SourceHistoryLaws, Self> {
79 match self.source_history_laws() {
80 Some(laws) => Ok(laws),
81 None => Err(self),
82 }
83 }
84
85 pub const fn require_land(self) -> Result<SourceHistoryLaws, Self> {
87 match self.source_history_laws() {
88 Some(laws) => Ok(laws),
89 None => Err(self),
90 }
91 }
92
93 pub const fn require_git_projection(self) -> Result<SourceHistoryLaws, Self> {
95 match self.source_history_laws() {
96 Some(laws) => Ok(laws),
97 None => Err(self),
98 }
99 }
100}
101
102impl fmt::Display for FacetKind {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 f.write_str(self.as_str())
105 }
106}
107
108impl SourceHistoryLaws {
109 pub const fn may_checkout(self) -> bool {
110 true
111 }
112
113 pub const fn may_land(self) -> bool {
114 true
115 }
116
117 pub const fn git_projection_visits(self) -> bool {
118 true
119 }
120}
121
122const _: () = assert!(FacetKind::SourceHistory.git_projection_visits());
123const _: () = assert!(FacetKind::SourceHistory.may_checkout());
124const _: () = assert!(FacetKind::SourceHistory.may_land());
125const _: () = assert!(!FacetKind::ConfidentialRuntime.git_projection_visits());
126const _: () = assert!(!FacetKind::ConfidentialRuntime.may_checkout());
127const _: () = assert!(!FacetKind::ConfidentialRuntime.may_land());
128const _: () = assert!(!FacetKind::Collaboration.git_projection_visits());
129const _: () = assert!(!FacetKind::AgentTimeline.git_projection_visits());
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn only_source_history_has_projection_checkout_and_land_laws() {
137 for kind in FacetKind::ALL {
138 let allowed = kind == FacetKind::SourceHistory;
139 assert_eq!(kind.may_checkout(), allowed, "{kind}");
140 assert_eq!(kind.may_land(), allowed, "{kind}");
141 assert_eq!(kind.git_projection_visits(), allowed, "{kind}");
142 assert_eq!(kind.source_history_laws().is_some(), allowed, "{kind}");
143 }
144 }
145
146 #[test]
147 fn confidential_runtime_is_refused_at_every_source_history_chokepoint() {
148 let kind = FacetKind::ConfidentialRuntime;
149 assert_eq!(kind.require_worktree_materialization(), Err(kind));
150 assert_eq!(kind.require_land(), Err(kind));
151 assert_eq!(kind.require_git_projection(), Err(kind));
152 }
153
154 #[test]
155 fn source_history_laws_are_the_only_projectable_token() {
156 let laws = FacetKind::SourceHistory
157 .source_history_laws()
158 .expect("source history yields laws");
159 assert!(laws.may_checkout());
160 assert!(laws.may_land());
161 assert!(laws.git_projection_visits());
162 }
163}