macroonz_compiler/explanation/
encode.rs1use super::{ExplanationIssue, RelatedDisposition, UniversalAnswer};
8use crate::identity::{encode_bytes, encode_length};
9use crate::kind::{Answer, Disposition, Question};
10
11fn disposition_into(disposition: Disposition, into: &mut Vec<u8>) {
13 match disposition {
14 Disposition::Generated { unit } => {
15 into.push(0);
16 encode_bytes(unit.as_bytes(), into);
17 }
18 Disposition::NotApplicable { because } => {
19 into.push(1);
20 encode_bytes(&because.citation_bytes(), into);
21 }
22 Disposition::NotRequested { because } => {
23 into.push(2);
24 encode_bytes(&because.citation_bytes(), into);
25 }
26 Disposition::UnavailableUnderProfile { profile, because } => {
27 into.push(3);
28 profile.encode_into(into);
29 encode_bytes(&because.citation_bytes(), into);
30 }
31 }
32}
33
34fn related_into(related: &RelatedDisposition, into: &mut Vec<u8>) {
36 encode_bytes(related.kind.as_bytes(), into);
37 disposition_into(related.disposition, into);
38}
39
40pub(super) fn answer_material(answer: &UniversalAnswer, into: &mut Vec<u8>) {
44 match answer {
45 UniversalAnswer::Kind { name } => encode_bytes(name.as_bytes(), into),
46 UniversalAnswer::Owner { owner } => encode_bytes(&owner.citation_bytes(), into),
47 UniversalAnswer::CausingDeclarations {
48 commitment,
49 dependencies,
50 } => {
51 encode_bytes(commitment.as_bytes(), into);
52 encode_length(dependencies.len(), into);
53 for dependency in dependencies.iter() {
54 encode_bytes(dependency.as_bytes(), into);
55 }
56 }
57 UniversalAnswer::Profile { profile } => profile.encode_into(into),
58 UniversalAnswer::OutputAndDigest { outputs } => {
59 encode_length(outputs.len(), into);
60 for row in outputs.iter() {
61 row.output.encode_into(into);
62 encode_bytes(row.digest.as_bytes(), into);
63 }
64 }
65 UniversalAnswer::Assumptions { assumptions } => {
66 encode_length(assumptions.len(), into);
67 for assumption in assumptions.iter() {
68 encode_bytes(&assumption.citation_bytes(), into);
69 }
70 }
71 UniversalAnswer::Invalidators { triggers } => {
72 encode_length(triggers.count(), into);
73 for trigger in triggers.iter() {
74 trigger.encode_into(into);
75 }
76 }
77 UniversalAnswer::RelatedDispositions { related } => {
78 encode_length(related.len(), into);
79 for accounted in related.iter() {
80 related_into(accounted, into);
81 }
82 }
83 UniversalAnswer::Repairs { repairs } => {
84 encode_length(repairs.len(), into);
85 for repair in repairs.iter() {
86 encode_bytes(&repair.declared_by.citation_bytes(), into);
87 }
88 }
89 }
90}
91
92pub(super) fn seats_into<A: Answer>(answers: &[A], into: &mut Vec<u8>) {
97 encode_length(answers.len(), into);
98 for answer in answers {
99 into.extend_from_slice(&answer.question().slot().to_be_bytes());
100 answer.encode_into(into);
101 }
102}
103
104impl ExplanationIssue {
105 #[must_use]
107 pub fn canonical_bytes(&self) -> Vec<u8> {
108 let mut bytes = Vec::new();
109 self.encode_into(&mut bytes);
110 bytes
111 }
112
113 pub fn encode_into(&self, into: &mut Vec<u8>) {
117 into.push(self.slot());
118 let mut material = Vec::new();
119 self.material_into(&mut material);
120 encode_bytes(&material, into);
121 }
122
123 fn material_into(&self, into: &mut Vec<u8>) {
125 match self {
126 Self::UniversalUnanswered { question } | Self::UniversalAnsweredTwice { question } => {
127 into.extend_from_slice(&question.slot().to_be_bytes());
128 }
129 Self::DeclaredUnanswered { question, slot }
130 | Self::DeclaredAnsweredTwice { question, slot } => {
131 encode_bytes(question.as_bytes(), into);
132 into.extend_from_slice(&slot.to_be_bytes());
133 }
134 Self::QuestionOutsideRoster { question } => encode_bytes(question.as_bytes(), into),
135 Self::SeatBoundExceeded { bound, observed } => {
136 into.extend_from_slice(&bound.to_be_bytes());
137 into.extend_from_slice(&observed.to_be_bytes());
138 }
139 Self::OutputsBesideTheProof {
140 expected,
141 observed,
142 diverges,
143 } => {
144 into.extend_from_slice(&expected.to_be_bytes());
145 into.extend_from_slice(&observed.to_be_bytes());
146 into.extend_from_slice(&diverges.to_be_bytes());
147 }
148 }
149 }
150}