1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
use crate::bumpalo::Bump; use crate::console::Console; use crate::context::Context; use crate::value::Value; use async_trait::async_trait; #[async_trait(?Send)] pub trait Builtin { async fn run<'c, C: Console>(&mut self, name: &'_ str, ctx: &'_ mut Context<'c>, console: &mut C) -> Option<Value<'c>>; fn load<'b>(&mut self, name: &str, b: &'b Bump) -> Value<'b>; } #[async_trait(?Send)] impl<'a, B: Builtin> Builtin for &'a mut B { #[inline] async fn run<'c, C: Console>(&mut self, name: &'_ str, ctx: &'_ mut Context<'c>, console: &mut C) -> Option<Value<'c>> { (**self).run(name, ctx, console).await } #[inline] fn load<'b>(&mut self, name: &str, b: &'b Bump) -> Value<'b> { (**self).load(name, b) } } pub struct DummyBuiltin; #[async_trait(?Send)] impl<'a> Builtin for DummyBuiltin { #[inline] async fn run<'c, C: Console>(&mut self, _name: &'_ str, _ctx: &'_ mut Context<'c>, _console: &mut C) -> Option<Value<'c>> { None } #[inline] fn load<'b>(&mut self, _name: &str, _b: &'b Bump) -> Value<'b> { Value::Int(0) } } #[cfg(test)] pub struct RecordBuiltin(pub String); #[cfg(test)] impl RecordBuiltin { #[inline] pub fn new() -> Self { Self(String::with_capacity(8196)) } } #[cfg(test)] #[async_trait(?Send)] impl Builtin for RecordBuiltin { #[inline] async fn run<'c, C: Console>(&'_ mut self, name: &'_ str, _ctx: &'_ mut Context<'c>, _console: &'_ mut C) -> Option<Value<'c>> { self.0.push_str(name); None } #[inline] fn load<'b>(&mut self, name: &str, _b: &'b Bump) -> Value<'b> { self.0.push('$'); self.0.push_str(name); Value::Int(0) } }