pub struct ThingBuilder<Other, Status>where
Other: ExtendableThing,{
pub other: Other,
/* private fields */
}Expand description
A builder for a Thing
A ThingBuilder can be created using ThingBuilder::new or Thing::builder, and after
all the customization, ThingBuilder::build needs to be called in order to create a
Thing.
Fields§
§other: OtherThing extension.
Implementations§
Source§impl<Other> ThingBuilder<Other, ToExtend>where
Other: ExtendableThing,
impl<Other> ThingBuilder<Other, ToExtend>where
Other: ExtendableThing,
Sourcepub fn new(title: impl Into<String>) -> ThingBuilder<Other, ToExtend>where
Other: Default,
pub fn new(title: impl Into<String>) -> ThingBuilder<Other, ToExtend>where
Other: Default,
Create a new default builder with a specified title, using a default extension
Sourcepub fn new_empty(
title: impl Into<String>,
) -> ThingBuilder<<Other as Extendable>::Empty, ToExtend>
pub fn new_empty( title: impl Into<String>, ) -> ThingBuilder<<Other as Extendable>::Empty, ToExtend>
Create a new default builder with a specified title, using an empty extension
Sourcepub fn finish_extend(self) -> ThingBuilder<Other, Extended>
pub fn finish_extend(self) -> ThingBuilder<Other, Extended>
Finalize the set of extensions that must be populated
Moves the builder status from ToExtend to Extended. From this point is not possible to add further extensions to the builder.
See ThingBuilder::ext.
§Example
let thing = Thing::builder("Thing name")
.id("thing-id-1234")
.finish_extend()
.property("first-property", |prop_builder| {
prop_builder
.finish_extend_data_schema()
.observable(true)
.bool()
})
.build()
.unwrap();Sourcepub fn ext_with<F, T>(
self,
f: F,
) -> ThingBuilder<<Other as Extend<T>>::Target, ToExtend>
pub fn ext_with<F, T>( self, f: F, ) -> ThingBuilder<<Other as Extend<T>>::Target, ToExtend>
Extends the Thing, passing a closure that returns T.
§Example
let thing = Thing::builder("Thing name")
.ext_with(|| ThingExtension {
a_field: "hello world".to_string(),
another_field: 42,
})
.finish_extend()
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"title": "Thing name",
"a_field": "hello world",
"another_field": 42,
"security": [],
"securityDefinitions": {},
})
);Sourcepub fn ext<T>(
self,
t: T,
) -> ThingBuilder<<Other as Extend<T>>::Target, ToExtend>
pub fn ext<T>( self, t: T, ) -> ThingBuilder<<Other as Extend<T>>::Target, ToExtend>
Extend the ThingBuilder with a ExtendableThing
§Example
let thing = Thing::builder("Thing name")
.ext(ThingExtension {
a_field: "hello world".to_string(),
another_field: 42,
})
.finish_extend()
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"title": "Thing name",
"a_field": "hello world",
"another_field": 42,
"security": [],
"securityDefinitions": {},
})
);Source§impl<Other, Status> ThingBuilder<Other, Status>where
Other: ExtendableThing,
impl<Other, Status> ThingBuilder<Other, Status>where
Other: ExtendableThing,
Sourcepub fn build(self) -> Result<Thing<Other>, Error>
pub fn build(self) -> Result<Thing<Other>, Error>
Consume the builder to produce the configured Thing
This step will perform the final validation of the builder state.
Sourcepub fn id(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn id(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
Sets the value of the id field.
Sourcepub fn description(
self,
value: impl Into<String>,
) -> ThingBuilder<Other, Status>
pub fn description( self, value: impl Into<String>, ) -> ThingBuilder<Other, Status>
Sets the value of the description field.
Sourcepub fn version(
self,
value: impl Into<VersionInfo>,
) -> ThingBuilder<Other, Status>
pub fn version( self, value: impl Into<VersionInfo>, ) -> ThingBuilder<Other, Status>
Sets the value of the version field.
Sourcepub fn created(
self,
value: impl Into<OffsetDateTime>,
) -> ThingBuilder<Other, Status>
pub fn created( self, value: impl Into<OffsetDateTime>, ) -> ThingBuilder<Other, Status>
Sets the value of the created field.
Sourcepub fn modified(
self,
value: impl Into<OffsetDateTime>,
) -> ThingBuilder<Other, Status>
pub fn modified( self, value: impl Into<OffsetDateTime>, ) -> ThingBuilder<Other, Status>
Sets the value of the modified field.
Sourcepub fn support(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn support(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
Sets the value of the support field.
Sourcepub fn base(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn base(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
Sets the value of the base field.
Sourcepub fn context<S>(self, value: S) -> ThingBuilder<Other, Status>
pub fn context<S>(self, value: S) -> ThingBuilder<Other, Status>
Add a new JSON-LD @context in the default namespace
Sourcepub fn context_map<F>(self, f: F) -> ThingBuilder<Other, Status>
pub fn context_map<F>(self, f: F) -> ThingBuilder<Other, Status>
Add a new JSON-LD @context with a custom namespace
§Example
let thing = Thing::builder("Thing name")
.context_map(|builder| {
builder
.context("custom_context1", "hello")
.context("custom_context2", "world")
})
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": [
"https://www.w3.org/2022/wot/td/v1.1",
{
"custom_context1": "hello",
"custom_context2": "world",
}
],
"security": [],
"securityDefinitions": {},
}),
);Sourcepub fn attype(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn attype(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
Add a JSON-LD @type to the thing
Sourcepub fn titles<F>(self, f: F) -> ThingBuilder<Other, Status>
pub fn titles<F>(self, f: F) -> ThingBuilder<Other, Status>
Set multi-language titles
§Examples
let thing = Thing::builder("Thing name")
.titles(|builder| {
builder
.add("en", "English title")
.add("it", "Italian title")
})
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"titles": {
"en": "English title",
"it": "Italian title",
},
"security": [],
"securityDefinitions": {},
})
);Creating a title using an invalid language tag is going to return an error when
Thing::build is called:
let error = Thing::builder("Thing name")
.titles(|builder| builder.add("e!n", "Invalid title"))
.build()
.unwrap_err();
assert_eq!(error, Error::InvalidLanguageTag("e!n".to_string()));Sourcepub fn descriptions<F>(self, f: F) -> ThingBuilder<Other, Status>
pub fn descriptions<F>(self, f: F) -> ThingBuilder<Other, Status>
Set multi-language descriptions
See ThingBuilder::titles for examples.
Sourcepub fn link(self, href: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn link(self, href: impl Into<String>) -> ThingBuilder<Other, Status>
Add an additional link to the Thing Description
Sourcepub fn link_with<F>(self, f: F) -> ThingBuilder<Other, Status>
pub fn link_with<F>(self, f: F) -> ThingBuilder<Other, Status>
Add an additional link to the Thing Description, with specified optional fields.
§Example
let thing = Thing::builder("Thing name")
.link_with(|builder| {
builder
.href("https://localhost")
.rel("icon")
.sizes("16x16 24x24 32x32")
})
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"links": [{
"href": "https://localhost",
"rel": "icon",
"sizes": "16x16 24x24 32x32",
}],
"security": [],
"securityDefinitions": {},
})
);Sourcepub fn security<F, T>(self, f: F) -> ThingBuilder<Other, Status>where
F: FnOnce(SecuritySchemeBuilder<()>) -> SecuritySchemeBuilder<T>,
T: BuildableSecuritySchemeSubtype,
pub fn security<F, T>(self, f: F) -> ThingBuilder<Other, Status>where
F: FnOnce(SecuritySchemeBuilder<()>) -> SecuritySchemeBuilder<T>,
T: BuildableSecuritySchemeSubtype,
Add a security definition and, eventually, a required security
§Example
let thing = Thing::builder("Thing name")
.security(|builder| {
builder
.basic()
.with_key("my_basic_sec")
.name("basic_sec_name")
})
.security(|builder| builder.apikey())
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"security": [],
"securityDefinitions": {
"my_basic_sec": {
"scheme": "basic",
"name": "basic_sec_name",
"in": "header",
},
"apikey": {
"scheme": "apikey",
"in": "query",
}
},
})
);Sourcepub fn profile(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
pub fn profile(self, value: impl Into<String>) -> ThingBuilder<Other, Status>
Adds a new item to the profile field.
Source§impl<Other> ThingBuilder<Other, Extended>
impl<Other> ThingBuilder<Other, Extended>
Sourcepub fn form<F>(self, f: F) -> ThingBuilder<Other, Extended>where
F: FnOnce(FormBuilder<Other, (), <<Other as ExtendableThing>::Form as Extendable>::Empty>) -> FormBuilder<Other, String, <Other as ExtendableThing>::Form>,
pub fn form<F>(self, f: F) -> ThingBuilder<Other, Extended>where
F: FnOnce(FormBuilder<Other, (), <<Other as ExtendableThing>::Form as Extendable>::Empty>) -> FormBuilder<Other, String, <Other as ExtendableThing>::Form>,
Add a Thing-level form
§Notes
- It must explicitly state its operation
- It must use an
alloperation
§Examples
let thing = Thing::builder("Thing name")
// Needs to _finish_ extending the thing before calling `.form`
.finish_extend()
.form(|builder| {
builder
.href("form_href")
.op(FormOperation::ReadAllProperties)
})
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"forms": [
{
"href": "form_href",
"op": ["readallproperties"],
}
],
"security": [],
"securityDefinitions": {},
})
);Thing-level forms must explicitly specify the operation, otherwise ThingBuilder::build
returns an error:
let error = Thing::builder("Thing name")
.finish_extend()
.form(|builder| builder.href("form_href"))
.build()
.unwrap_err();
assert_eq!(error, Error::MissingOpInForm);Furthermore, Thing-level form operations must be one or more of the following
FormOperations:
ReadAllPropertiesWriteAllPropertiesObserveAllPropertiesUnobserveAllPropertiesSubscribeAllEventsUnsubscribeAllEventsQueryAllActions
If any other FormOperation is specified, ThingBuilder::build returns an error:
let error = Thing::builder("Thing name")
.finish_extend()
.form(|builder| builder.href("form_href").op(FormOperation::ReadProperty))
.build()
.unwrap_err();
assert_eq!(
error,
Error::InvalidOpInForm {
context: FormContext::Thing,
operation: FormOperation::ReadProperty,
}
);Source§impl<Other> ThingBuilder<Other, Extended>where
Other: ExtendableThing,
impl<Other> ThingBuilder<Other, Extended>where
Other: ExtendableThing,
Sourcepub fn uri_variable<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(DataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>) -> T,
T: Into<UncheckedDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>>,
<Other as ExtendableThing>::DataSchema: Extendable,
pub fn uri_variable<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(DataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>) -> T,
T: Into<UncheckedDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>>,
<Other as ExtendableThing>::DataSchema: Extendable,
Adds a new URI variable.
It takes a function that accepts a DataSchema builder and must return a
type convertible into a DataSchema.
See DataSchemaBuilder for more information about how the underlying builder works.
§Examples
let thing = Thing::builder("Thing name")
.finish_extend()
.uri_variable("var", |builder| builder.finish_extend().number())
.build()
.unwrap();
assert_eq!(
serde_json::to_value(thing).unwrap(),
json!({
"title": "Thing name",
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"uriVariables": {
"var": {
"type": "number",
"readOnly": false,
"writeOnly": false,
},
},
"security": [],
"securityDefinitions": {},
})
);Sourcepub fn property<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(PropertyAffordanceBuilder<Other, PartialDataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::PropertyAffordance as Extendable>::Empty>) -> T,
T: IntoUsable<PropertyAffordanceBuilder<Other, PartialDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::PropertyAffordance>>,
<Other as ExtendableThing>::DataSchema: Extendable,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::PropertyAffordance: Extendable,
pub fn property<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(PropertyAffordanceBuilder<Other, PartialDataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::PropertyAffordance as Extendable>::Empty>) -> T,
T: IntoUsable<PropertyAffordanceBuilder<Other, PartialDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::PropertyAffordance>>,
<Other as ExtendableThing>::DataSchema: Extendable,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::PropertyAffordance: Extendable,
Adds a new property affordance.
It takes a function that accepts a PropertyAffordance builder and must return a type
convertible into an usable PropertyAffordance builder.
See PropertyAffordanceBuilder for more information about how the underlying builder
works.
Sourcepub fn action<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(ActionAffordanceBuilder<Other, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::ActionAffordance as Extendable>::Empty>) -> T,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::ActionAffordance: Extendable,
T: IntoUsable<ActionAffordanceBuilder<Other, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::ActionAffordance>>,
pub fn action<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(ActionAffordanceBuilder<Other, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::ActionAffordance as Extendable>::Empty>) -> T,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::ActionAffordance: Extendable,
T: IntoUsable<ActionAffordanceBuilder<Other, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::ActionAffordance>>,
Adds a new action affordance.
It takes a function that accepts a ActionAffordance builder and must return a type
convertible into an usable ActionAffordance builder.
See ActionAffordanceBuilder for more information about how the underlying builder
works.
Sourcepub fn event<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(EventAffordanceBuilder<Other, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::EventAffordance as Extendable>::Empty>) -> T,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::EventAffordance: Extendable,
T: IntoUsable<EventAffordanceBuilder<Other, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::EventAffordance>>,
pub fn event<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(EventAffordanceBuilder<Other, <<Other as ExtendableThing>::InteractionAffordance as Extendable>::Empty, <<Other as ExtendableThing>::EventAffordance as Extendable>::Empty>) -> T,
<Other as ExtendableThing>::InteractionAffordance: Extendable,
<Other as ExtendableThing>::EventAffordance: Extendable,
T: IntoUsable<EventAffordanceBuilder<Other, <Other as ExtendableThing>::InteractionAffordance, <Other as ExtendableThing>::EventAffordance>>,
Adds a new event affordance.
It takes a function that accepts an EventAffordance builder and must return a type
convertible into an usable EventAffordance builder.
See EventAffordanceBuilder for more information about how the underlying builder works.
Sourcepub fn schema_definition<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(DataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>) -> T,
T: Into<UncheckedDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>>,
<Other as ExtendableThing>::DataSchema: Extendable,
pub fn schema_definition<F, T>(
self,
name: impl Into<String>,
f: F,
) -> ThingBuilder<Other, Extended>where
F: FnOnce(DataSchemaBuilder<<<Other as ExtendableThing>::DataSchema as Extendable>::Empty, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema, ToExtend>) -> T,
T: Into<UncheckedDataSchema<<Other as ExtendableThing>::DataSchema, <Other as ExtendableThing>::ArraySchema, <Other as ExtendableThing>::ObjectSchema>>,
<Other as ExtendableThing>::DataSchema: Extendable,
Adds a new schema definition.
It takes the name for the schema definition and a function that takes a DataSchema
builder and must return a type convertible into an unchecked DataSchema.
See DataSchemaBuilder for more information about how the underlying builder works.