1use alloc::collections::BTreeMap;
4use alloc::string::String;
5use alloc::vec::Vec;
6use serde::{Deserialize, Serialize};
7
8use crate::config::{ConfigSchema, ConfigValue};
9
10macro_rules! id_type {
11 ($name:ident) => {
12 #[derive(
13 Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
14 )]
15 #[serde(transparent)]
16 pub struct $name(pub u32);
17 };
18}
19
20id_type!(NodeId);
21id_type!(KernelId);
22id_type!(BufferId);
23id_type!(StepId);
24id_type!(FeedbackId);
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
27#[serde(transparent)]
28pub struct GraphId(pub [u8; 32]);
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
31#[serde(transparent)]
32pub struct PlanId(pub [u8; 32]);
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
35#[serde(transparent)]
36pub struct SubgraphId(pub [u8; 32]);
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
39#[serde(transparent)]
40pub struct ImplementationId(pub [u8; 32]);
41
42#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
43pub struct NodeTypeRef {
44 pub type_name: String,
45 pub version: u32,
46}
47
48#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
49#[serde(transparent)]
50pub struct Capability(pub String);
51
52#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
70#[serde(transparent)]
71pub struct Target(u32);
72
73#[allow(non_upper_case_globals)]
74impl Target {
75 pub const McuAot: Self = Self(0);
77 pub const Host: Self = Self(1);
79 pub const BlutDurable: Self = Self(2);
81
82 pub const KNOWN: [Self; 3] = [Self::McuAot, Self::Host, Self::BlutDurable];
84
85 pub const fn token(self) -> u32 {
88 self.0
89 }
90
91 pub const fn from_token(token: u32) -> Self {
94 Self(token)
95 }
96
97 pub const fn is_known(self) -> bool {
103 self.0 <= 2
104 }
105
106 const fn name(self) -> Option<&'static str> {
107 match self.0 {
108 0 => Some("McuAot"),
109 1 => Some("Host"),
110 2 => Some("BlutDurable"),
111 _ => None,
112 }
113 }
114}
115
116impl core::fmt::Debug for Target {
117 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118 match self.name() {
119 Some(name) => formatter.write_str(name),
120 None => write!(formatter, "Target({})", self.0),
121 }
122 }
123}
124
125#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
128#[serde(transparent)]
129pub struct ExecutionRealm(u32);
130
131#[allow(non_upper_case_globals)]
132impl ExecutionRealm {
133 pub const McuAot: Self = Self(0);
135 pub const HostStream: Self = Self(1);
137 pub const BlutDurable: Self = Self(2);
139
140 pub const KNOWN: [Self; 3] = [Self::McuAot, Self::HostStream, Self::BlutDurable];
142
143 pub const fn token(self) -> u32 {
144 self.0
145 }
146
147 pub const fn from_token(token: u32) -> Self {
148 Self(token)
149 }
150
151 pub const fn is_known(self) -> bool {
152 self.0 <= 2
153 }
154
155 pub const fn target(self) -> Target {
162 match self.0 {
163 0 => Target::McuAot,
164 1 => Target::Host,
165 2 => Target::BlutDurable,
166 other => Target::from_token(other),
167 }
168 }
169
170 const fn name(self) -> Option<&'static str> {
171 match self.0 {
172 0 => Some("McuAot"),
173 1 => Some("HostStream"),
174 2 => Some("BlutDurable"),
175 _ => None,
176 }
177 }
178}
179
180impl core::fmt::Debug for ExecutionRealm {
181 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182 match self.name() {
183 Some(name) => formatter.write_str(name),
184 None => write!(formatter, "ExecutionRealm({})", self.0),
185 }
186 }
187}
188
189#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
190#[serde(rename_all = "kebab-case")]
191pub enum Determinism {
192 BitExact,
193 NumericallyEquivalent,
194 Seeded,
195 Nondeterministic,
196}
197
198#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
199#[serde(rename_all = "kebab-case")]
200pub enum Effect {
201 Pure,
202 Idempotent,
203 Transactional,
204 AtMostOnce,
205 AtLeastOnce,
206}
207
208#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
209#[serde(rename_all = "kebab-case")]
210pub enum Partiality {
211 Atomic,
213 ExplicitGaps,
215}
216
217#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
218pub struct FailureContract {
219 pub domains: Vec<String>,
221}
222
223#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
231#[serde(transparent)]
232pub struct Layout(u32);
233
234#[allow(non_upper_case_globals)]
235impl Layout {
236 pub const Canonical: Self = Self(0);
238 pub const ChannelMajor: Self = Self(1);
240 pub const TimeMajor: Self = Self(2);
242 pub const Packed: Self = Self(3);
244 pub const Opaque: Self = Self(4);
246
247 pub const KNOWN: [Self; 5] = [
249 Self::Canonical,
250 Self::ChannelMajor,
251 Self::TimeMajor,
252 Self::Packed,
253 Self::Opaque,
254 ];
255
256 pub const fn token(self) -> u32 {
257 self.0
258 }
259
260 pub const fn from_token(token: u32) -> Self {
261 Self(token)
262 }
263
264 pub const fn is_known(self) -> bool {
265 self.0 <= 4
266 }
267
268 const fn name(self) -> Option<&'static str> {
269 match self.0 {
270 0 => Some("Canonical"),
271 1 => Some("ChannelMajor"),
272 2 => Some("TimeMajor"),
273 3 => Some("Packed"),
274 4 => Some("Opaque"),
275 _ => None,
276 }
277 }
278}
279
280impl core::fmt::Debug for Layout {
281 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
282 match self.name() {
283 Some(name) => formatter.write_str(name),
284 None => write!(formatter, "Layout({})", self.0),
285 }
286 }
287}
288
289#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
309#[serde(transparent)]
310pub struct DomainToken(String);
311
312impl DomainToken {
313 pub fn new(value: impl Into<String>) -> Self {
314 Self(value.into())
315 }
316
317 pub fn as_str(&self) -> &str {
318 &self.0
319 }
320
321 pub fn is_empty(&self) -> bool {
322 self.0.is_empty()
323 }
324}
325
326impl From<&str> for DomainToken {
327 fn from(value: &str) -> Self {
328 Self(value.into())
329 }
330}
331
332impl From<String> for DomainToken {
333 fn from(value: String) -> Self {
334 Self(value)
335 }
336}
337
338#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
345pub struct DomainType {
346 pub root: DomainToken,
347 pub view: DomainToken,
348}
349
350impl DomainType {
351 pub fn new(root: impl Into<DomainToken>, view: impl Into<DomainToken>) -> Self {
352 Self {
353 root: root.into(),
354 view: view.into(),
355 }
356 }
357}
358
359#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
360pub struct ExtentContract {
361 pub rank: u8,
363 pub maximum_shape: Vec<u64>,
365 pub max_elements: u64,
366 pub ragged: bool,
367 pub sparse: bool,
368}
369
370#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
371#[serde(rename_all = "kebab-case")]
372pub enum LeaseAccess {
373 ReadOnly,
374 ExclusiveWrite,
375}
376
377#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
378#[serde(rename_all = "kebab-case")]
379pub enum LeaseLifetime {
380 Step,
381 Invocation,
382 Session,
383}
384
385#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
386pub struct LeaseContract {
387 pub access: LeaseAccess,
388 pub lifetime: LeaseLifetime,
389 pub zero_copy_permitted: bool,
390 pub contiguous_required: bool,
391}
392
393#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
394pub struct ResourceEnvelope {
395 pub peak_bytes: u64,
396 pub scratch_bytes: u64,
397 pub threads: u16,
398 pub device: Option<String>,
399}
400
401impl ResourceEnvelope {
402 pub const fn bounded(peak_bytes: u64, scratch_bytes: u64, threads: u16) -> Self {
403 Self {
404 peak_bytes,
405 scratch_bytes,
406 threads,
407 device: None,
408 }
409 }
410}
411
412#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
413pub struct PortDescriptor {
414 pub name: String,
415 pub semantic_type: String,
416 pub optional: bool,
417 pub layouts: Vec<Layout>,
418 pub max_bytes: u64,
419 pub domain: DomainType,
420 pub proof: ProofContract,
421 pub policy: PolicyContract,
422 pub fidelity: FidelityContract,
423 pub extent: ExtentContract,
424 pub lease: LeaseContract,
425}
426
427impl PortDescriptor {
428 pub fn opaque(
430 name: impl Into<String>,
431 semantic_type: impl Into<String>,
432 max_bytes: u64,
433 ) -> Self {
434 Self {
435 name: name.into(),
436 semantic_type: semantic_type.into(),
437 optional: false,
438 layouts: alloc::vec![Layout::Canonical],
439 max_bytes,
440 domain: DomainType {
441 root: DomainToken::new("blob-ref"),
442 view: DomainToken::new("atom"),
443 },
444 proof: ProofContract {
445 requires: Vec::new(),
446 provides: Vec::new(),
447 invalidates: Vec::new(),
448 },
449 policy: PolicyContract {
450 requires: Vec::new(),
451 adds: Vec::new(),
452 },
453 fidelity: FidelityContract {
454 minimum_input: 0,
455 maximum_loss: 0,
456 },
457 extent: ExtentContract {
458 rank: 0,
459 maximum_shape: Vec::new(),
460 max_elements: 1,
461 ragged: false,
462 sparse: false,
463 },
464 lease: LeaseContract {
465 access: LeaseAccess::ReadOnly,
466 lifetime: LeaseLifetime::Invocation,
467 zero_copy_permitted: false,
468 contiguous_required: false,
469 },
470 }
471 }
472}
473
474#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
475pub struct ProofContract {
476 pub requires: Vec<String>,
477 pub provides: Vec<String>,
478 pub invalidates: Vec<String>,
479}
480
481#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
482pub struct PolicyContract {
483 pub requires: Vec<String>,
484 pub adds: Vec<String>,
485}
486
487#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
488pub struct FidelityContract {
489 pub minimum_input: u16,
490 pub maximum_loss: u16,
491}
492
493#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
494#[serde(rename_all = "kebab-case")]
495pub enum StateScope {
496 Stateless,
497 Invocation,
498 Session,
499 Durable,
500}
501
502#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
503#[serde(rename_all = "kebab-case")]
504pub enum CheckpointMode {
505 Disabled,
506 Optional,
507 Required,
508}
509
510#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
511pub struct CheckpointContract {
512 pub mode: CheckpointMode,
513 pub max_snapshot_bytes: u64,
514 pub max_interval_invocations: u32,
515}
516
517#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
518pub struct StateContract {
519 pub scope: StateScope,
520 pub max_bytes: u64,
521 pub checkpoint: CheckpointContract,
522}
523
524impl StateContract {
525 pub const fn stateless() -> Self {
526 Self {
527 scope: StateScope::Stateless,
528 max_bytes: 0,
529 checkpoint: CheckpointContract {
530 mode: CheckpointMode::Disabled,
531 max_snapshot_bytes: 0,
532 max_interval_invocations: 0,
533 },
534 }
535 }
536
537 pub const fn checkpointable(&self) -> bool {
538 !matches!(self.checkpoint.mode, CheckpointMode::Disabled)
539 }
540}
541
542#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
543pub struct SessionContract {
544 pub namespace: String,
545 pub max_concurrent_sessions: u32,
546 pub max_idle_millis: u64,
547 pub reset_on_plan_change: bool,
548}
549
550#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
551pub struct DelayContract {
552 pub invocations: u32,
554 pub initial: DelayInitial,
555}
556
557#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
558#[serde(rename_all = "kebab-case")]
559pub enum DelayInitial {
560 Absent,
561 Zeroed,
562 ContentId([u8; 32]),
563}
564
565#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
566pub struct FeedbackEdge {
567 pub from: PortRef,
568 pub to: PortRef,
569 pub delay: DelayContract,
570}
571
572#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
573pub struct PortMap {
574 pub outer: String,
575 pub inner: String,
576}
577
578#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
579pub struct SubgraphConfigMap {
580 pub outer: String,
582 pub node: NodeId,
584 pub inner: String,
586}
587
588#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
589pub struct SubgraphLowering {
590 pub subgraph: SubgraphId,
591 pub input_map: Vec<PortMap>,
592 pub output_map: Vec<PortMap>,
593 pub config_map: Vec<SubgraphConfigMap>,
595}
596
597#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
598pub struct SubgraphNode {
599 pub id: NodeId,
601 pub node_type: NodeTypeRef,
602 pub config: BTreeMap<String, ConfigValue>,
603 pub child: Option<SubgraphId>,
605}
606
607#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
608pub struct SubgraphInterfacePort {
609 pub name: String,
610 pub inner: PortRef,
611}
612
613#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
614pub struct SubgraphSchema {
615 pub id: SubgraphId,
616 pub version: u32,
617 pub nodes: Vec<SubgraphNode>,
618 pub edges: Vec<Edge>,
619 pub inputs: Vec<SubgraphInterfacePort>,
620 pub outputs: Vec<SubgraphInterfacePort>,
621}
622
623#[derive(Clone, Debug, PartialEq, Eq)]
624pub struct MaterializedSubgraph {
625 pub graph: Graph,
626 pub inputs: Vec<SubgraphInterfacePort>,
628 pub outputs: Vec<SubgraphInterfacePort>,
630}
631
632#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
633pub struct NodeDescriptor {
634 pub type_name: String,
635 pub version: u32,
636 pub inputs: Vec<PortDescriptor>,
637 pub outputs: Vec<PortDescriptor>,
638 pub capabilities: Vec<Capability>,
639 pub targets: Vec<Target>,
640 pub resources: ResourceEnvelope,
641 pub determinism: Determinism,
642 pub config: ConfigSchema,
643 pub state: StateContract,
644 pub subgraph: Option<SubgraphLowering>,
645 pub proof: ProofContract,
646 pub policy: PolicyContract,
647 pub fidelity: FidelityContract,
648 pub partiality: Partiality,
649 pub failure: FailureContract,
650 pub effect: Effect,
651 pub retry_limit: u16,
652}
653
654#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
655pub struct NodeInstance {
656 pub id: NodeId,
657 pub descriptor: String,
658 pub descriptor_version: u32,
659 pub config: BTreeMap<String, ConfigValue>,
660}
661
662#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
663pub struct PortRef {
664 pub node: NodeId,
665 pub port: String,
666}
667
668#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
669pub struct Edge {
670 pub from: PortRef,
671 pub to: PortRef,
672}
673
674#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
675pub struct Graph {
676 pub version: u32,
677 pub nodes: Vec<NodeInstance>,
678 pub edges: Vec<Edge>,
679 #[serde(default)]
682 pub feedback: Vec<FeedbackEdge>,
683 #[serde(default)]
687 pub invocation_inputs: Vec<PortRef>,
688 pub required_capabilities: Vec<Capability>,
689 pub required_proofs: Vec<String>,
690 pub policy: Vec<String>,
691 pub minimum_fidelity: u16,
692 pub session: Option<SessionContract>,
693}
694
695#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
696pub struct KernelDescriptor {
697 pub id: KernelId,
698 pub implements: Vec<NodeTypeRef>,
701 pub implementation_id: ImplementationId,
704 pub conversion: Option<LayoutConversion>,
708 pub target: Target,
709 pub input_layouts: Vec<Layout>,
710 pub output_layouts: Vec<Layout>,
711 pub resources: ResourceEnvelope,
712 pub determinism: Determinism,
713 pub lowering: String,
714}
715
716#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
717pub struct LayoutConversion {
718 pub semantic_type: String,
719 pub from: Layout,
720 pub to: Layout,
721 pub max_input_bytes: u64,
722 pub max_output_bytes: u64,
723}
724
725#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
726#[serde(rename_all = "kebab-case")]
727pub enum OutputBinding {
728 Buffer(BufferId),
729 Terminal,
730}
731
732#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
733#[serde(rename_all = "kebab-case")]
734pub enum InputBinding {
735 Buffer(BufferId),
736 Invocation(u32),
737 Feedback(FeedbackId),
738 Absent,
739}
740
741#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
742pub struct CompiledPortContract {
743 pub name: String,
744 pub semantic_type: String,
745 pub optional: bool,
746 pub layout: Layout,
747 pub max_bytes: u64,
748 pub domain: DomainType,
749 pub proof: ProofContract,
750 pub policy: PolicyContract,
751 pub fidelity: FidelityContract,
752 pub extent: ExtentContract,
753 pub lease: LeaseContract,
754}
755
756impl CompiledPortContract {
757 pub fn opaque(
758 name: impl Into<String>,
759 semantic_type: impl Into<String>,
760 layout: Layout,
761 max_bytes: u64,
762 ) -> Self {
763 let port = PortDescriptor::opaque(name, semantic_type, max_bytes);
764 Self {
765 name: port.name,
766 semantic_type: port.semantic_type,
767 optional: port.optional,
768 layout,
769 max_bytes: port.max_bytes,
770 domain: port.domain,
771 proof: port.proof,
772 policy: port.policy,
773 fidelity: port.fidelity,
774 extent: port.extent,
775 lease: port.lease,
776 }
777 }
778}
779
780#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
781pub struct CompiledNode {
782 pub id: StepId,
785 pub semantic_nodes: Vec<NodeId>,
788 pub semantic_types: Vec<NodeTypeRef>,
791 pub semantic_configs: Vec<BTreeMap<String, ConfigValue>>,
794 pub kernel: KernelId,
795 pub implementation_id: ImplementationId,
796 pub resources: ResourceEnvelope,
797 pub determinism: Determinism,
798 pub lowering: String,
799 pub conversion: Option<LayoutConversion>,
800 pub input_ports: Vec<String>,
802 pub output_ports: Vec<String>,
803 pub input_contracts: Vec<CompiledPortContract>,
804 pub output_contracts: Vec<CompiledPortContract>,
805 pub input_bindings: Vec<InputBinding>,
807 pub output_bindings: Vec<OutputBinding>,
810 pub partiality: Partiality,
811 pub failure: FailureContract,
812 pub effect: Effect,
813 pub retry_limit: u16,
814 pub state: StateContract,
815 pub subgraph_path: Vec<SubgraphId>,
817}
818
819#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
820pub struct FeedbackPlan {
821 pub id: FeedbackId,
822 pub from_step: StepId,
823 pub from_port: u32,
824 pub to_step: StepId,
825 pub to_port: u32,
826 pub delay: DelayContract,
827 pub state_bytes: u64,
828}
829
830#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
831pub struct BufferPlan {
832 pub id: BufferId,
833 pub layout: Layout,
834 pub capacity_bytes: u64,
835 pub producer: StepId,
836 pub consumers: Vec<StepId>,
837 pub last_consumer: StepId,
839 pub aliases: Option<BufferId>,
840}
841
842#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
843pub struct CompiledPlan {
844 pub schema_version: u32,
845 pub graph_id: GraphId,
846 pub plan_id: PlanId,
847 pub realm: ExecutionRealm,
848 pub order: Vec<NodeId>,
849 pub nodes: Vec<CompiledNode>,
850 pub buffers: Vec<BufferPlan>,
851 pub feedback: Vec<FeedbackPlan>,
852 pub invocation_ports: Vec<PortRef>,
854 pub propagated_proofs: Vec<String>,
855 pub propagated_policy: Vec<String>,
856 pub resulting_fidelity: u16,
857 pub peak_bytes: u64,
861 pub persistent_state_bytes: u64,
863 pub session: Option<SessionContract>,
864}
865
866#[derive(Clone, Debug, PartialEq, Eq)]
871pub struct AuthorizedPlan {
872 plan: CompiledPlan,
873}
874
875impl AuthorizedPlan {
876 pub(crate) const fn new(plan: CompiledPlan) -> Self {
877 Self { plan }
878 }
879
880 pub const fn as_plan(&self) -> &CompiledPlan {
881 &self.plan
882 }
883
884 pub fn into_plan(self) -> CompiledPlan {
885 self.plan
886 }
887}
888
889impl core::ops::Deref for AuthorizedPlan {
890 type Target = CompiledPlan;
891
892 fn deref(&self) -> &Self::Target {
893 &self.plan
894 }
895}