Skip to main content

sark_core/body/credit/raw/
bind.rs

1use crate::body::{self, buffered, credit, 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: storage, track and credit all move together; only the proof changes.
28unsafe impl<S, O: credit::Origin> credit::raw::Bind for buffered::State<S, O> {
29    type Origin = O;
30    type Bound<Q: credit::Origin> = buffered::State<S, Q>;
31
32    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
33        buffered::State {
34            // SAFETY: this is the exact ingress owned by the authenticated buffer.
35            state: unsafe { self.state.bind(origin) },
36            storage: self.storage,
37        }
38    }
39}
40
41// SAFETY: every failure variant retains the exact same source and obligation.
42unsafe impl<S, T, O: credit::Origin> credit::raw::Bind for buffered::Rejected<S, T, O> {
43    type Origin = O;
44    type Bound<Q: credit::Origin> = buffered::Rejected<S, T, Q>;
45
46    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
47        match self {
48            Self::Admission { state, error } => buffered::Rejected::Admission {
49                // SAFETY: the caller authenticates this exact rejected owner.
50                state: unsafe { state.bind(origin) },
51                error,
52            },
53            Self::Storage { failure, release } => buffered::Rejected::Storage {
54                failure,
55                // SAFETY: the original release remains paired with its source.
56                release: unsafe { release.bind(origin) },
57            },
58            Self::Credit {
59                body,
60                release,
61                error,
62            } => buffered::Rejected::Credit {
63                body,
64                // SAFETY: the original release remains paired with its source.
65                release: unsafe { release.bind(origin) },
66                error,
67            },
68        }
69    }
70}
71
72// SAFETY: the builder/output and ingress ownership move unchanged together.
73unsafe impl<'d, B: body::Build<'d>, O: credit::Origin> credit::raw::Bind
74    for stream::Stream<'d, B, O>
75{
76    type Origin = O;
77    type Bound<Q: credit::Origin> = stream::Stream<'d, B, Q>;
78
79    unsafe fn bind<Q: credit::Origin>(self, origin: Q) -> Self::Bound<Q> {
80        // SAFETY: the caller authenticates this exact stream's persistent custody.
81        stream::Stream::from_parts(unsafe { self.state.bind(origin) }, self.flow)
82    }
83}