Skip to main content

sark_core/body/credit/raw/
bind.rs

1use crate::body::{self, buffered, credit, flow, ingress, stream};
2
3// SAFETY: only the account proof changes; the exact amount remains owned once.
4unsafe impl<O: credit::Origin> credit::raw::Bind for credit::Release<O> {
5    type Origin = O;
6    type Bound<Q: credit::Origin> = credit::Release<Q>;
7
8    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
9        credit::Release::new(self.amount, origin)
10    }
11}
12
13// SAFETY: the exact track and unreleased credit move unchanged with the new proof.
14unsafe impl<O: credit::Origin> credit::raw::Bind for ingress::State<O> {
15    type Origin = O;
16    type Bound<Q: credit::Origin> = ingress::State<Q>;
17
18    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
19        ingress::State {
20            track: self.track,
21            credit: self.credit,
22            origin,
23        }
24    }
25}
26
27// SAFETY: the finished track and all its credit remain in the same owner.
28unsafe impl<O: credit::Origin> credit::raw::Bind for ingress::Finished<O> {
29    type Origin = O;
30    type Bound<Q: credit::Origin> = ingress::Finished<Q>;
31
32    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
33        // SAFETY: the caller authenticates the enclosing finished owner's account.
34        ingress::Finished {
35            state: unsafe { self.state.bind(origin) },
36        }
37    }
38}
39
40// SAFETY: storage, track and credit all move together; only the proof changes.
41unsafe impl<S, O: credit::Origin> credit::raw::Bind for buffered::State<S, O> {
42    type Origin = O;
43    type Bound<Q: credit::Origin> = buffered::State<S, Q>;
44
45    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
46        buffered::State {
47            // SAFETY: this is the exact ingress owned by the authenticated buffer.
48            state: unsafe { self.state.bind(origin) },
49            storage: self.storage,
50        }
51    }
52}
53
54// SAFETY: every failure variant retains the exact same source and obligation.
55unsafe impl<S, T, O: credit::Origin> credit::raw::Bind for buffered::Rejected<S, T, O> {
56    type Origin = O;
57    type Bound<Q: credit::Origin> = buffered::Rejected<S, T, Q>;
58
59    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
60        match self {
61            Self::Admission { state, error } => buffered::Rejected::Admission {
62                // SAFETY: the caller authenticates this exact rejected owner.
63                state: unsafe { state.bind(origin) },
64                error,
65            },
66            Self::Storage { failure, release } => buffered::Rejected::Storage {
67                failure,
68                // SAFETY: the original release remains paired with its source.
69                release: unsafe { release.bind(origin) },
70            },
71            Self::Credit {
72                body,
73                release,
74                error,
75            } => buffered::Rejected::Credit {
76                body,
77                // SAFETY: the original release remains paired with its source.
78                release: unsafe { release.bind(origin) },
79                error,
80            },
81        }
82    }
83}
84
85// SAFETY: the builder/output and ingress ownership move unchanged together.
86unsafe impl<'d, B: body::Build<'d>, O: credit::Origin> credit::raw::Bind
87    for stream::Stream<'d, B, O>
88{
89    type Origin = O;
90    type Bound<Q: credit::Origin> = stream::Stream<'d, B, Q>;
91
92    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
93        // SAFETY: the caller authenticates this exact stream's persistent custody.
94        stream::Stream::from_parts(unsafe { self.state.bind(origin) }, self.flow)
95    }
96}
97
98// SAFETY: the finished owner and built output move unchanged with the new proof.
99unsafe impl<'d, B: body::Build<'d>, O: credit::Origin> credit::raw::Bind for flow::Ready<'d, B, O> {
100    type Origin = O;
101    type Bound<Q: credit::Origin> = flow::Ready<'d, B, Q>;
102
103    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
104        flow::Ready {
105            // SAFETY: this is the exact ingress retained by the authenticated output.
106            state: unsafe { self.state.bind(origin) },
107            output: self.output,
108            lifetime: self.lifetime,
109        }
110    }
111}