Skip to content

Commit 22a022a

Browse files
Add support for ranges
1 parent e688869 commit 22a022a

File tree

2 files changed

+65
-12
lines changed

2 files changed

+65
-12
lines changed

rclrs-macros/src/impl.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro2::TokenStream;
22
use quote::quote;
3-
use syn::{token::Token, DeriveInput, Expr};
3+
use syn::{DeriveInput, Expr};
44

55
pub(crate) fn derive_structured_parameters(input: DeriveInput) -> syn::Result<TokenStream> {
66
let ident = input.ident;
@@ -34,6 +34,7 @@ fn derive_structured_parameters_struct(
3434
let mut ignore_override = false;
3535
let mut discard_mismatching_prior_value = false;
3636
let mut discriminate: Option<Expr> = None;
37+
let mut range: Option<Expr> = None;
3738

3839
for attr in &f.attrs {
3940
if attr.path().is_ident("param") {
@@ -56,6 +57,9 @@ fn derive_structured_parameters_struct(
5657
} else if meta.path.is_ident("discriminate") {
5758
discriminate = Some(meta.value()?.parse()?);
5859
Ok(())
60+
} else if meta.path.is_ident("range") {
61+
range = Some(meta.value()?.parse()?);
62+
Ok(())
5963
} else {
6064
let err = format!("Unknown key: {:?}", &meta.path.get_ident());
6165
syn::Result::Err(syn::Error::new_spanned(meta.path, err))
@@ -82,6 +86,12 @@ fn derive_structured_parameters_struct(
8286
},
8387
None => quote! {core::option::Option::None},
8488
};
89+
let range = match range {
90+
Some(expr) => quote! {
91+
core::option::Option::Some(#expr)
92+
},
93+
None => quote! {core::option::Option::None},
94+
};
8595

8696
let field_type = match &f.ty {
8797
syn::Type::Path(p) => {
@@ -111,7 +121,7 @@ fn derive_structured_parameters_struct(
111121
#ignore_override,
112122
#discard_mismatching_prior_value,
113123
#discriminate,
114-
124+
#range,
115125
)?,
116126
};
117127
args.push(r);
@@ -130,15 +140,16 @@ fn derive_structured_parameters_struct(
130140
fn declare_structured_(
131141
node: &rclrs::NodeState,
132142
name: &str,
133-
default: core::option::Option<rclrs::structured::DefaultForbidden>,
143+
default: core::option::Option<rclrs::parameter::structured::DefaultForbidden>,
134144
description: impl core::convert::Into<std::sync::Arc<str>>,
135145
constraints: impl core::convert::Into<std::sync::Arc<str>>,
136146
ignore_override: bool,
137147
discard_mismatching_prior_value: bool,
138148
discriminate: core::option::Option<Box<
139-
dyn core::ops::FnOnce(rclrs::AvailableValues<rclrs::structured::DefaultForbidden>)
140-
-> core::option::Option<rclrs::structured::DefaultForbidden
149+
dyn core::ops::FnOnce(rclrs::AvailableValues<rclrs::parameter::structured::DefaultForbidden>)
150+
-> core::option::Option<rclrs::parameter::structured::DefaultForbidden
141151
>>>,
152+
range: core::option::Option<<rclrs::structured::DefaultForbidden as rclrs::ParameterVariant>::Range>,
142153
)
143154
-> core::result::Result<Self, rclrs::DeclarationError> {
144155
core::result::Result::Ok(Self{ #(#args)*})

rclrs/src/parameter/structured.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,36 @@
44
55
use crate::NodeState;
66

7+
use super::ParameterVariant;
8+
79
/// Marker trait for implementing [`StructuredParameters`] where a default value cannot be specified.
810
/// This is usually the case for container types, that are not represented by any actual parameter.
11+
12+
#[derive(Clone, Copy)]
913
pub enum DefaultForbidden {}
14+
impl crate::ParameterVariant for DefaultForbidden {
15+
type Range = ();
16+
17+
fn kind() -> crate::ParameterKind {
18+
// cannot be instantiated cannot be called
19+
// let's satisfy the type checker
20+
unreachable!()
21+
}
22+
}
23+
impl From<DefaultForbidden> for crate::ParameterValue {
24+
fn from(_value: DefaultForbidden) -> Self {
25+
// cannot be instantiated cannot be called
26+
// let's satisfy the type checker
27+
unreachable!()
28+
}
29+
}
30+
impl From<crate::ParameterValue> for DefaultForbidden {
31+
fn from(_value: crate::ParameterValue) -> Self {
32+
// cannot be instantiated cannot be called
33+
// let's satisfy the type checker
34+
unreachable!()
35+
}
36+
}
1037

1138
/// Types implementing this trait can delcare their parameters with[`NodeState::declare_parameters`].
1239
/// The trait can be automatically derived using [`rclrs_proc_macros`] if:
@@ -25,7 +52,7 @@ pub trait StructuredParameters: Sized {
2552
/// # Returns
2653
///
2754
/// [`Result`] containing the declared structured parameters or [`crate::DeclarationError`]
28-
fn declare_structured<T>(
55+
fn declare_structured<T: ParameterVariant>(
2956
node: &NodeState,
3057
name: &str,
3158
default: Option<T>,
@@ -34,6 +61,7 @@ pub trait StructuredParameters: Sized {
3461
ignore_override: bool,
3562
discard_mismatching_prior_value: bool,
3663
discriminate: Option<Box<dyn FnOnce(crate::AvailableValues<T>) -> Option<T>>>,
64+
range: Option<<T as crate::ParameterVariant>::Range>,
3765
) -> core::result::Result<Self, crate::DeclarationError>
3866
where
3967
Self: StructuredParametersMeta<T>,
@@ -47,6 +75,7 @@ pub trait StructuredParameters: Sized {
4775
ignore_override,
4876
discard_mismatching_prior_value,
4977
discriminate,
78+
range,
5079
)
5180
}
5281
}
@@ -62,7 +91,7 @@ pub trait StructuredParameters: Sized {
6291
/// and therefore we can hide this form the trait + macro by using this helper trait.
6392
/// The previously mentioned leaf types that actually hold parameters, are to be implemented manually anyway.
6493
///
65-
pub trait StructuredParametersMeta<T>: Sized {
94+
pub trait StructuredParametersMeta<T: ParameterVariant>: Sized {
6695
/// See [`StructuredParameters::declare_structured`]
6796
fn declare_structured_(
6897
node: &NodeState,
@@ -73,20 +102,21 @@ pub trait StructuredParametersMeta<T>: Sized {
73102
ignore_override: bool,
74103
discard_mismatching_prior_value: bool,
75104
discriminate: Option<Box<dyn FnOnce(crate::AvailableValues<T>) -> Option<T>>>,
105+
range: Option<<T as crate::ParameterVariant>::Range>,
76106
) -> core::result::Result<Self, crate::DeclarationError>;
77107
}
78108

79109
impl NodeState {
80110
/// Declares all nested parameters of the [`StructuredParameters`].
81111
/// Parameter naming recursively follows "`name`.`field_name`" or "`field_name`" if the initial `name` is empty.
82-
pub fn declare_parameters<T, T0>(
112+
pub fn declare_parameters<T, T0: ParameterVariant>(
83113
&self,
84114
name: &str,
85115
) -> core::result::Result<T, crate::DeclarationError>
86116
where
87117
T: StructuredParameters + StructuredParametersMeta<T0>,
88118
{
89-
T::declare_structured(self, name, None, "", "", false, false, None)
119+
T::declare_structured(self, name, None, "", "", false, false, None, None)
90120
}
91121
}
92122

@@ -101,6 +131,7 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::Mandator
101131
ignore_override: bool,
102132
discard_mismatching_prior_value: bool,
103133
discriminate: Option<Box<dyn FnOnce(crate::AvailableValues<T>) -> Option<T>>>,
134+
range: Option<<T as crate::ParameterVariant>::Range>,
104135
) -> core::result::Result<Self, crate::DeclarationError> {
105136
let builder = node.declare_parameter(name);
106137
let builder = match default {
@@ -119,8 +150,10 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::Mandator
119150
Some(f) => builder.discriminate(f),
120151
None => builder,
121152
};
122-
//builder.range(range)
123-
153+
let builder = match range {
154+
Some(range) => builder.range(range),
155+
None => builder,
156+
};
124157
builder
125158
.description(description)
126159
.constraints(constraints)
@@ -138,6 +171,7 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::ReadOnly
138171
ignore_override: bool,
139172
discard_mismatching_prior_value: bool,
140173
discriminate: Option<Box<dyn FnOnce(crate::AvailableValues<T>) -> Option<T>>>,
174+
range: Option<<T as crate::ParameterVariant>::Range>,
141175
) -> core::result::Result<Self, crate::DeclarationError> {
142176
let builder = node.declare_parameter(name);
143177
let builder = match default {
@@ -156,6 +190,10 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::ReadOnly
156190
Some(f) => builder.discriminate(f),
157191
None => builder,
158192
};
193+
let builder = match range {
194+
Some(range) => builder.range(range),
195+
None => builder,
196+
};
159197
builder
160198
.description(description)
161199
.constraints(constraints)
@@ -173,6 +211,7 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::Optional
173211
ignore_override: bool,
174212
discard_mismatching_prior_value: bool,
175213
discriminate: Option<Box<dyn FnOnce(crate::AvailableValues<T>) -> Option<T>>>,
214+
range: Option<<T as crate::ParameterVariant>::Range>,
176215
) -> core::result::Result<Self, crate::DeclarationError> {
177216
let builder = node.declare_parameter(name);
178217
let builder = match default {
@@ -191,7 +230,10 @@ impl<T: crate::ParameterVariant> StructuredParametersMeta<T> for crate::Optional
191230
Some(f) => builder.discriminate(f),
192231
None => builder,
193232
};
194-
233+
let builder = match range {
234+
Some(range) => builder.range(range),
235+
None => builder,
236+
};
195237
builder
196238
.description(description)
197239
.constraints(constraints)

0 commit comments

Comments
 (0)