Skip to main content

capnp/private/
capability.rs

1// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
2// Licensed under the MIT License:
3//
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8// copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20// THE SOFTWARE.
21
22#![cfg(feature = "alloc")]
23
24use crate::any_pointer;
25use crate::capability::{Params, Promise, RemotePromise, Request, Results};
26use crate::MessageSize;
27
28pub trait ResponseHook {
29    fn get(&self) -> crate::Result<any_pointer::Reader<'_>>;
30}
31
32pub trait RequestHook {
33    fn get(&mut self) -> any_pointer::Builder<'_>;
34    fn get_brand(&self) -> usize;
35    fn send(self: alloc::boxed::Box<Self>) -> RemotePromise<any_pointer::Owned>;
36    fn send_streaming(self: alloc::boxed::Box<Self>) -> Promise<(), crate::Error>;
37    fn tail_send(
38        self: alloc::boxed::Box<Self>,
39    ) -> Option<(
40        u32,
41        crate::capability::Promise<(), crate::Error>,
42        alloc::boxed::Box<dyn PipelineHook>,
43    )>;
44}
45
46pub trait ClientHook {
47    fn add_ref(&self) -> alloc::boxed::Box<dyn ClientHook>;
48    fn new_call(
49        &self,
50        interface_id: u64,
51        method_id: u16,
52        size_hint: Option<MessageSize>,
53    ) -> Request<any_pointer::Owned, any_pointer::Owned>;
54
55    fn call(
56        &self,
57        interface_id: u64,
58        method_id: u16,
59        params: alloc::boxed::Box<dyn ParamsHook>,
60        results: alloc::boxed::Box<dyn ResultsHook>,
61    ) -> crate::capability::Promise<(), crate::Error>;
62
63    /// If this capability is associated with an rpc connection, then this method
64    /// returns an identifier for that connection.
65    fn get_brand(&self) -> usize;
66
67    /// Returns a (locally) unique identifier for this capability.
68    fn get_ptr(&self) -> usize;
69
70    /// If this ClientHook is a promise that has already resolved, returns the inner, resolved version
71    /// of the capability.  The caller may permanently replace this client with the resolved one if
72    /// desired.  Returns null if the client isn't a promise or hasn't resolved yet -- use
73    /// `whenMoreResolved()` to distinguish between them.
74    fn get_resolved(&self) -> Option<alloc::boxed::Box<dyn ClientHook>>;
75
76    /// If this client is a settled reference (not a promise), return nullptr.  Otherwise, return a
77    /// promise that eventually resolves to a new client that is closer to being the final, settled
78    /// client (i.e. the value eventually returned by `getResolved()`).  Calling this repeatedly
79    /// should eventually produce a settled client.
80    fn when_more_resolved(
81        &self,
82    ) -> Option<crate::capability::Promise<alloc::boxed::Box<dyn ClientHook>, crate::Error>>;
83
84    /// Repeatedly calls whenMoreResolved() until it returns nullptr.
85    fn when_resolved(&self) -> Promise<(), crate::Error>;
86}
87
88impl Clone for alloc::boxed::Box<dyn ClientHook> {
89    fn clone(&self) -> Self {
90        self.add_ref()
91    }
92}
93
94pub trait ResultsHook {
95    fn get(&mut self) -> crate::Result<any_pointer::Builder<'_>>;
96
97    fn set_pipeline(&mut self) -> crate::Result<()>;
98
99    fn allow_cancellation(&self);
100    fn tail_call(
101        self: alloc::boxed::Box<Self>,
102        request: alloc::boxed::Box<dyn RequestHook>,
103    ) -> Promise<(), crate::Error>;
104    fn direct_tail_call(
105        self: alloc::boxed::Box<Self>,
106        request: alloc::boxed::Box<dyn RequestHook>,
107    ) -> (
108        crate::capability::Promise<(), crate::Error>,
109        alloc::boxed::Box<dyn PipelineHook>,
110    );
111}
112
113pub trait ParamsHook {
114    fn get(&self) -> crate::Result<crate::any_pointer::Reader<'_>>;
115}
116
117// Where should this live?
118pub fn internal_get_typed_params<T>(typeless: Params<any_pointer::Owned>) -> Params<T> {
119    Params {
120        hook: typeless.hook,
121        marker: ::core::marker::PhantomData,
122    }
123}
124
125pub fn internal_get_typed_results<T>(typeless: Results<any_pointer::Owned>) -> Results<T> {
126    Results {
127        hook: typeless.hook,
128        marker: ::core::marker::PhantomData,
129    }
130}
131
132pub fn internal_get_untyped_results<T>(typeful: Results<T>) -> Results<any_pointer::Owned> {
133    Results {
134        hook: typeful.hook,
135        marker: ::core::marker::PhantomData,
136    }
137}
138
139pub trait PipelineHook {
140    fn add_ref(&self) -> alloc::boxed::Box<dyn PipelineHook>;
141    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> alloc::boxed::Box<dyn ClientHook>;
142
143    /// Version of get_pipelined_cap() passing the array by move. May avoid a copy in some cases.
144    /// Default implementation just calls the other version.
145    fn get_pipelined_cap_move(
146        &self,
147        ops: alloc::vec::Vec<PipelineOp>,
148    ) -> alloc::boxed::Box<dyn ClientHook> {
149        self.get_pipelined_cap(&ops)
150    }
151}
152
153impl Clone for alloc::boxed::Box<dyn PipelineHook> {
154    fn clone(&self) -> Self {
155        self.add_ref()
156    }
157}
158
159#[derive(Clone, Copy)]
160pub enum PipelineOp {
161    Noop,
162    GetPointerField(u16),
163}