rusteval/
specialization.rs1#![allow(missing_docs)]
3
4use core::any::type_name;
5use core::fmt::Debug;
6
7use crate::{Interactive, InteractiveError, Methods, Result};
8
9macro_rules! duck_type {
12 ($vis:vis $AsTrait:ident ($method:ident) : $Trait:path | $Error:ident) => {
13 $vis trait $AsTrait {
14 fn $method(&self) -> Result<'_, &dyn $Trait>;
15 }
16
17 impl<T> $AsTrait for T {
18 default fn $method(&self) -> Result<'_, &dyn $Trait> {
19 Err(InteractiveError::$Error {
20 type_name: type_name::<T>(),
21 })
22 }
23 }
24
25 impl<T> $AsTrait for T
26 where
27 T: $Trait,
28 {
29 fn $method(&self) -> Result<'_, &dyn $Trait> {
30 Ok(self)
31 }
32 }
33 };
34}
35
36macro_rules! duck_type_mut {
39 ($vis:vis $AsTrait:ident ($method:ident) : $Trait:path | $Error:ident) => {
40 $vis trait $AsTrait {
41 fn $method(&mut self) -> Result<'_, &mut dyn $Trait>;
42 }
43
44 impl<T> $AsTrait for T {
45 default fn $method(&mut self) -> Result<'_, &mut dyn $Trait> {
46 Err(InteractiveError::$Error {
47 type_name: type_name::<T>(),
48 })
49 }
50 }
51
52 impl<T> $AsTrait for T
53 where
54 T: $Trait,
55 {
56 fn $method(&mut self) -> Result<'_, &mut dyn $Trait> {
57 Ok(self)
58 }
59 }
60 };
61}
62
63duck_type!(pub AsInteractive(try_as_interactive): Interactive | InteractiveNotImplemented);
64
65duck_type_mut!(pub AsInteractiveMut(try_as_interactive_mut): Interactive | InteractiveNotImplemented);
66duck_type!(pub AsMethods(try_as_methods): Methods | MethodsNotImplemented);
67
68duck_type_mut!(pub AsMethodsMut(try_as_methods_mut): Methods | MethodsNotImplemented);
69duck_type!(pub AsDebug(try_as_debug): Debug | DebugNotImplemented);
70
71macro_rules! deref_for_interactive {
74 ($AsTrait:ident ($method:ident) : $Trait:path) => {
75 impl $AsTrait for &dyn Interactive {
76 fn $method(&self) -> Result<'_, &dyn $Trait> {
77 (&**self).$method()
78 }
79 }
80
81 impl $AsTrait for &mut dyn Interactive {
82 fn $method(&self) -> Result<'_, &dyn $Trait> {
83 (&**self).$method()
84 }
85 }
86 };
87}
88
89macro_rules! deref_for_interactive_mut {
92 ($AsTrait:ident ($method:ident) : $Trait:path) => {
93 impl $AsTrait for &mut dyn Interactive {
94 fn $method(&mut self) -> Result<'_, &mut dyn $Trait> {
95 (&mut **self).$method()
96 }
97 }
98 };
99}
100
101deref_for_interactive!(AsMethods(try_as_methods): Methods);
102deref_for_interactive_mut!(AsMethodsMut(try_as_methods_mut): Methods);
103deref_for_interactive!(AsDebug(try_as_debug): Debug);
104
105#[allow(missing_copy_implementations)]
107#[derive(Debug)]
108pub struct Unknown;