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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! Contains convenience macros for declaring types for the Koto runtime
compile_error!;
use TokenStream;
/// `#[derive(KotoType)]`
///
/// The `KotoType` trait will be implemented using the name of the struct.
/// If another name should be displayed in the Koto runtime then use
/// `#[koto(type_name = "other_name)]`.
///
/// ## Example
///
/// ```ignore
/// // Derive a KotoType implementation using 'KotoFoo' as the type name.
/// #[derive(KotoType)]
/// struct KotoFoo {}
///
/// // Derive a KotoType implementation using 'Bar' as the type name.
/// #[derive(KotoType)]
/// #[koto(type_name = "Bar")]
/// struct KotoBar {}
/// ```
/// `#[derive(KotoCopy)]`
///
/// The `KotoCopy` trait will be implemented using the struct's `Clone` implementation.
///
/// If the struct implements `Copy` then that should most likely be used instead.
/// I haven't found an automatic way to detect that the struct implements `Copy`,
/// so use the `#[koto(use_copy)]` attribute to tell the macro that `Copy` is available.
///
/// ## Example
///
/// ```ignore
/// // Derive a KotoCopy implementation using KotoFoo's Clone implementation
/// #[derive(Clone, KotoCopy)]
/// struct KotoFoo {}
///
/// // Derive a KotoCopy implementation using KotoBar's Copy implementation
/// #[derive(Copy, Clone, KotoCopy)]
/// #[koto(use_copy)]
/// struct KotoBar {}
/// ```
/// A helper for deriving `KotoEntries` with functions tagged with `#[koto_method]`
///
/// Any function tagged with `#[koto_method]` will be made available via '.' lookup.
///
/// Wrapper functions are generated that take care of checking that the function has been called
/// with an instance of the correct object type.
///
/// The function can take `&self` or `&mut self` along with an optional `&[KValue]` slice of
/// additional arguments, or for more advanced functions a `MethodContext<Self>` can be provided.
///
/// The return type can be ommitted (in which case the result will be `KValue::Null`),
/// or a `KValue`, or a `Result<KValue>`.
///
/// For cases where it would be preferable to return a clone of the object instance
/// (e.g. if you want to implement chainable setters), then you can accept a `MethodContext<Self`>
/// as the function argument and then return `MethodContext::instance_result()`.
///
/// ## `runtime` attribute
///
/// The macro generates code assuming that the top-level `koto` crate is being used,
/// with the koto_runtime crate re-exported at `::koto::runtime`.
/// If the runtime crate is located at a different path (e.g., if your crate depends on
/// `koto_runtime` directly), then use the `runtime` attribute to define the alternative path,
/// e.g. `#[koto_impl(runtime = koto_runtime)]`.
///
/// ## Example
///
/// ```ignore
/// #[derive(Clone, KotoType, KotoCopy)]
/// struct Foo {
/// x: f64
/// }
///
/// #[koto_impl]
/// impl Foo {
/// fn new(x: f64) -> Self {
/// Self { x }
/// }
///
/// // Add an `x()` method to the Foo object, and also make it available via `get_x()`
/// #[koto_method(alias = "get_x")]
/// fn x(&self) -> KValue {
/// self.x.into()
/// }
///
/// // A wrapper function
/// #[koto_method]
/// fn reset(&mut self, args: &[KValue]) -> Result<KValue> {
/// let reset_value = match args {
/// [] => 0.0,
/// [KValue::Number(reset_value)] => reset_value.into(),
/// unexpected => return unexpected_args("||, or |Number|", unexpected),
/// };
/// self.x = reset_value;
/// Ok(())
/// }
///
/// #[koto_method]
/// fn set_x(ctx: MethodContext) -> Result<KValue> {
/// match args {
/// [KValue::Number(new_x)] => {
/// ctx.instance_mut()?.x = new_x.into();
/// // Return a clone of the instance that's being modified
/// ctx.instance_result()
/// }
/// unexpected => unexpected_args("|Number|", unexpected),
/// }
/// }
/// }
///
///
/// ```
/// See [`koto_impl`](macro@koto_impl)