linkspace/
argument_traits.rs1pub use try_as::TryAsSpace;
3
4pub mod try_as {
5 use linkspace_core::space_expr::SpaceExpr;
6
7 use crate::prelude::*;
8
9 pub trait TryAsSpace {
10 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space>;
11 }
12 impl<T: TryAsSpace + ?Sized> TryAsSpace for &T {
13 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
14 T::try_as_space(*self, scope)
15 }
16 }
17 impl TryAsSpace for Space {
18 fn try_as_space(&self, _scope: &dyn LkEnv) -> anyhow::Result<Space> {
19 Ok(*self)
20 }
21 }
22 impl TryAsSpace for (Domain, GroupID, &LkPath) {
23 fn try_as_space(&self, _scope: &dyn LkEnv) -> anyhow::Result<Space> {
24 Ok(Space {
25 domain: self.0,
26 group: self.1,
27 path: self.2.to_array(),
28 })
29 }
30 }
31 impl TryAsSpace for &dyn Point {
32 fn try_as_space(&self, _scope: &dyn LkEnv) -> anyhow::Result<Space> {
33 Ok(Space {
34 domain: *self.get_domain(),
35 group: *self.get_group(),
36 path: self.get_path().to_array(),
37 })
38 }
39 }
40 impl<T: TryAsSpace + Sized> TryAsSpace for (Domain, T) {
41 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
42 let mut space = self.1.try_as_space(scope)?;
43 space.domain = self.0;
44 Ok(space)
45 }
46 }
47 impl TryAsSpace for LkPath {
48 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
49 SpaceExpr::try_from(self)?.eval(scope.as_scope().as_dyn())
50 }
51 }
52 impl TryAsSpace for LkPathArray {
53 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
54 self.as_path().try_as_space(scope)
55 }
56 }
57 impl TryAsSpace for &[&[u8]] {
58 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
59 SpaceExpr::from_scope_local(
60 None,
61 None,
62 linkspace_core::point::LkPathArray::try_from_iter(self.iter())?.into(),
63 )?
64 .eval(scope.as_scope().as_dyn())
65 }
66 }
67 impl TryAsSpace for str {
69 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
70 let se: SpaceExpr = self.parse()?;
71 se.eval(scope.as_scope().as_dyn())
72 }
73 }
74 impl TryAsSpace for SpaceExpr {
75 fn try_as_space(&self, scope: &dyn LkEnv) -> anyhow::Result<Space> {
76 self.eval(scope.as_scope().as_dyn())
77 }
78 }
79}
80
81pub use work_env::LkEnv;
82pub mod work_env {
83 use linkspace_core::abe::eval::ScopeSet;
84 use linkspace_core::point::AsPointPtr;
85 use linkspace_core::space_expr::SubSpace;
86 use linkspace_system::thread_local::set_system;
87
88 use crate::prelude::*;
89 use crate::system::lks_current;
90 use crate::work_env::*;
91 pub trait LkEnv {
96 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>);
97 fn as_scope(&self) -> LkaScope {
98 let mut ud = LkEnvData::default();
99 self.userdata(&mut ud);
100 ud.into()
101 }
102 }
103 impl LkEnv for (&dyn LkEnv, &dyn LkEnv) {
104 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
105 self.0.userdata(out);
106 self.1.userdata(out);
107 }
108 }
109 impl LkEnv for Option<&dyn LkEnv> {
110 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
111 if let Some(wv) = self {
112 wv.userdata(out);
113 }
114 }
115 }
116
117 impl<'o> From<LkEnvData<'o>> for LkaScope<'o> {
118 fn from(ud: LkEnvData<'o>) -> Self {
119 LkaScope(InlineScope::Std(ScopeSet(ud)))
120 }
121 }
122 impl LkEnv for () {
123 fn userdata<'o>(&'o self, _out: &mut LkEnvData<'o>) {}
124 }
125 impl LkEnv for LkEnvData<'_> {
126 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
127 *out = *self;
128 }
129 }
130 impl LkEnv for &dyn Point {
131 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
132 out.point = Some(self);
133 }
134 }
135 impl LkEnv for (&dyn Point, &[&[u8]]) {
136 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
137 out.point = Some(self.0);
138 out.argv = Some(self.1);
139 }
140 }
141 impl LkEnv for (Option<&dyn Point>, Option<&[&[u8]]>) {
142 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
143 out.point = self.0;
144 out.argv = self.1;
145 }
146 }
147 impl LkEnv for &[&[u8]] {
148 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
149 out.argv = Some(self)
150 }
151 }
152 impl<const N: usize> LkEnv for [&[u8]; N] {
153 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
154 out.argv = Some(self);
155 }
156 }
157 impl LkEnv for LkaScope<'_> {
158 fn userdata<'o>(&'o self, _out: &mut LkEnvData<'o>) {}
159 fn as_scope(&self) -> LkaScope {
160 self.clone()
161 }
162 }
163 impl LkEnv for Space {
164 fn userdata<'o>(&'o self, out: &mut crate::work_env::LkEnvData<'o>) {
165 out.domain = Some(&self.domain);
166 out.group = Some(&self.group);
167 }
168 }
169 impl LkEnv for SubSpace {
170 fn userdata<'o>(&'o self, out: &mut crate::work_env::LkEnvData<'o>) {
171 self.space.userdata(out);
172 out.pubkey = self.pubkey.as_ref()
173 }
174 }
175 impl LkEnv for LkIdentity {
176 fn userdata<'o>(&'o self, out: &mut crate::work_env::LkEnvData<'o>) {
177 out.key = Some(self);
178 }
179 }
180 impl LkEnv for (Domain, GroupID, PubKey) {
181 fn userdata<'o>(&'o self, out: &mut crate::work_env::LkEnvData<'o>) {
182 out.domain = Some(&self.0);
183 out.group = Some(&self.1);
184 out.pubkey = Some(&self.2);
185 }
186 }
187 impl LkEnv for (Domain, GroupID) {
188 fn userdata<'o>(&'o self, out: &mut crate::work_env::LkEnvData<'o>) {
189 out.domain = Some(&self.0);
190 out.group = Some(&self.1);
191 }
192 }
193 impl LkEnv for LkEnvDataSync {
194 fn userdata<'o>(&'o self, out: &mut LkEnvData<'o>) {
195 let LkEnvDataSync {
196 point,
197 argv,
198 domain,
199 group,
200 pubkey,
201 key,
202 lksi,
203 } = self;
204 if let Some(lksi) = lksi {
205 if let Some(current) = lks_current() {
208 let info = system::lks_info(Some(¤t)).unwrap();
209 assert!(
210 info.name == lksi.name && info.kind == lksi.kind,
211 "FIXME: Setting LKS via LkEnvDataSync is not supported beyond setting the global system"
212 );
213 };
214 let lks = crate::system::lks_from_info(lksi).expect("bad LksInfo?");
215
216 unsafe {
217 set_system(lks.into());
218 }
219 }
220 out.point = point.as_ref().map(|o| o.as_netptr() as &dyn Point);
221 if argv.is_some() {
222 unimplemented!("TODO: argv should be serializable");
223 }
224 out.domain = domain.as_ref();
225 out.group = group.as_ref();
226 out.pubkey = pubkey.as_ref();
227 out.key = key.as_ref();
228 }
229 }
230}
231
232pub use stmnts::Stmnts;
233pub mod stmnts {
234 use crate::{LkQuery, LkResult};
235 pub trait Stmnts {
236 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()>;
237 }
238 impl Stmnts for &[u8] {
239 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
240 per_line(self)
241 }
242 }
243 impl Stmnts for &str {
244 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
245 per_line(self.as_bytes())
246 }
247 }
248 impl Stmnts for LkQuery {
249 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
250 self.to_string().per_line(per_line)
251 }
252 }
253 impl Stmnts for String {
254 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
255 per_line(self.as_bytes())
256 }
257 }
258 impl Stmnts for () {
259 fn per_line(&self, _per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
260 Ok(())
261 }
262 }
263 impl<X: Stmnts> Stmnts for &[X] {
264 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
265 self.iter().try_for_each(|o| o.per_line(per_line))
266 }
267 }
268 impl<const L: usize, X: Stmnts> Stmnts for [X; L] {
269 fn per_line(&self, per_line: &mut dyn FnMut(&[u8]) -> LkResult<()>) -> LkResult<()> {
270 self.iter().try_for_each(|o| o.per_line(per_line))
271 }
272 }
273}