Skip to content

Commit 6640417

Browse files
author
David Rajchenbach-Teller
committed
Merge pull request #15 from azasypkin/boolean-values
Introduce boolean-like value types (fixes #13) - wip.
2 parents e7e6981 + fb2344e commit 6640417

File tree

2 files changed

+132
-18
lines changed

2 files changed

+132
-18
lines changed

src/services.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use serde::de::{Deserialize, Deserializer, Error};
1919
pub struct ServiceId;
2020

2121
/// Metadata on a service. A service is a device or collection of devices
22-
/// that may offer services. The FoxBox itself a service offering
23-
/// services such as a clock, communication with the user through her
22+
/// that may offer services. The FoxBox itself is a service offering
23+
/// services such as a clock, communicating with the user through her
2424
/// smart devices, etc.
2525
#[derive(Debug, Clone, Serialize, Deserialize)]
2626
pub struct Service {
@@ -134,13 +134,14 @@ impl ChannelKind {
134134
/// Get the type of values used to communicate with this service.
135135
pub fn get_type(&self) -> Type {
136136
use self::ChannelKind::*;
137-
use values::Type::*;
137+
use values::Type;
138138
match *self {
139-
Ready => Unit,
140-
OnOff | OpenClosed => Bool,
141-
CurrentTime => TimeStamp,
142-
CurrentTimeOfDay | RemainingTime => Duration,
143-
Thermostat | ActualTemperature => Temperature,
139+
Ready => Type::Unit,
140+
OnOff => Type::OnOff,
141+
OpenClosed => Type::OpenClosed,
142+
CurrentTime => Type::TimeStamp,
143+
CurrentTimeOfDay | RemainingTime => Type::Duration,
144+
Thermostat | ActualTemperature => Type::Temperature,
144145
Extension { ref typ, ..} => typ.clone(),
145146
}
146147
}

src/values.rs

+123-10
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ pub enum Type {
3333
/// has reached 0 or that a device is ready.
3434
Unit,
3535

36-
/// A boolean. Used for instance for on-off switches, presence
37-
/// detectors, etc.
38-
Bool,
36+
///
37+
/// # Boolean values
38+
///
39+
40+
/// A boolean on/off state. Used for various two-states switches.
41+
OnOff,
42+
43+
/// A boolean open/closed state. Used for instance for doors,
44+
/// windows, etc.
45+
OpenClosed,
3946

4047
///
4148
/// # Time
@@ -56,6 +63,8 @@ pub enum Type {
5663
Color,
5764
Json,
5865
Binary,
66+
67+
ExtBool,
5968
ExtNumeric,
6069
}
6170

@@ -67,11 +76,68 @@ impl Type {
6776
use self::Type::*;
6877
match *self {
6978
Duration | TimeStamp | Temperature | ExtNumeric | Color => false,
70-
Unit | Bool | String | Json | Binary => true,
79+
Unit | String | Json | Binary | OnOff | OpenClosed | ExtBool => true,
80+
}
81+
}
82+
}
83+
84+
/// An on/off state. Internal representation may be either On or Off.
85+
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
86+
pub enum OnOff {
87+
On,
88+
Off,
89+
}
90+
91+
impl OnOff {
92+
fn as_bool(&self) -> bool {
93+
match *self {
94+
OnOff::On => true,
95+
OnOff::Off => false,
96+
}
97+
}
98+
}
99+
100+
impl PartialOrd for OnOff {
101+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
102+
Some(self.cmp(other))
103+
}
104+
}
105+
106+
impl Ord for OnOff {
107+
fn cmp(&self, other: &Self) -> Ordering {
108+
self.as_bool().cmp(&other.as_bool())
109+
}
110+
}
111+
112+
/// An open/closed state. Internal representation may be either
113+
/// Open or Closed.
114+
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
115+
pub enum OpenClosed {
116+
Open,
117+
Closed,
118+
}
119+
120+
impl OpenClosed {
121+
fn as_bool(&self) -> bool {
122+
match *self {
123+
OpenClosed::Open => true,
124+
OpenClosed::Closed => false,
71125
}
72126
}
73127
}
74128

129+
impl PartialOrd for OpenClosed {
130+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
131+
Some(self.cmp(other))
132+
}
133+
}
134+
135+
impl Ord for OpenClosed {
136+
fn cmp(&self, other: &Self) -> Ordering {
137+
self.as_bool().cmp(&other.as_bool())
138+
}
139+
}
140+
75141
/// A temperature. Internal representation may be either Fahrenheit or
76142
/// Celcius. The FoxBox adapters are expected to perform conversions
77143
/// to the format requested by their devices.
@@ -123,6 +189,40 @@ impl PartialOrd for Json {
123189
}
124190
}
125191

192+
/// A data structure holding a boolean value of a type that has not
193+
/// been standardized yet.
194+
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
195+
pub struct ExtBool {
196+
pub value: bool,
197+
198+
/// The vendor. Used for namespacing purposes, to avoid
199+
/// confusing two incompatible extensions with similar
200+
/// names. For instance, "[email protected]".
201+
pub vendor: String,
202+
203+
/// Identification of the adapter introducing this value.
204+
/// Designed to aid with tracing and debugging.
205+
pub adapter: String,
206+
207+
/// A string describing the nature of the value, designed to
208+
/// aid with type-checking.
209+
///
210+
/// Examples: `"PresenceDetected"`.
211+
pub kind: String,
212+
}
213+
214+
impl PartialOrd for ExtBool {
215+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
216+
if self.vendor != other.vendor {
217+
return None;
218+
} else if self.kind != other.kind {
219+
return None;
220+
}
221+
222+
self.value.partial_cmp(&other.value)
223+
}
224+
}
225+
126226
/// A data structure holding a numeric value of a type that has not
127227
/// been standardized yet.
128228
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -162,7 +262,8 @@ impl PartialOrd for ExtNumeric {
162262
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
163263
pub enum Value {
164264
Unit,
165-
Bool(bool),
265+
OnOff(OnOff),
266+
OpenClosed(OpenClosed),
166267
Duration(ValDuration),
167268
TimeStamp(TimeStamp),
168269
Temperature(Temperature),
@@ -171,18 +272,22 @@ pub enum Value {
171272

172273
// FIXME: Add more as we identify needs
173274

275+
/// A boolean value representing a unit that has not been
276+
/// standardized yet into the API.
277+
ExtBool(ExtBool),
278+
174279
/// A numeric value representing a unit that has not been
175280
/// standardized yet into the API.
176281
ExtNumeric(ExtNumeric),
177282

178283
/// A Json value. We put it behind an `Arc` to make sure that
179-
/// cloning remains unexpensive.
284+
/// cloning remains inexpensive.
180285
Json(Arc<Json>),
181286

182287
/// Binary data.
183288
Binary {
184289
/// The actual data. We put it behind an `Arc` to make sure
185-
/// that cloning remains unexpensive.
290+
/// that cloning remains inexpensive.
186291
data: Arc<Vec<u8>>,
187292
mimetype: String
188293
}
@@ -192,14 +297,16 @@ impl Value {
192297
pub fn get_type(&self) -> Type {
193298
match *self {
194299
Value::Unit => Type::Unit,
195-
Value::Bool(_) => Type::Bool,
300+
Value::OnOff => Type::OnOff,
301+
Value::OpenClosed => Type::OpenClosed,
196302
Value::String(_) => Type::String,
197303
Value::Duration(_) => Type::Duration,
198304
Value::TimeStamp(_) => Type::TimeStamp,
199305
Value::Temperature(_) => Type::Temperature,
200306
Value::Color(_) => Type::Color,
201307
Value::Json(_) => Type::Json,
202308
Value::Binary{..} => Type::Binary,
309+
Value::ExtBool(_) => Type::ExtBool,
203310
Value::ExtNumeric(_) => Type::ExtNumeric,
204311
}
205312
}
@@ -230,8 +337,11 @@ impl PartialOrd for Value {
230337
(&Unit, &Unit) => Some(Equal),
231338
(&Unit, _) => None,
232339

233-
(&Bool(a), &Bool(b)) => a.partial_cmp(&b),
234-
(&Bool(_), _) => None,
340+
(&OnOff(ref a), &OnOff(ref b)) => a.partial_cmp(b),
341+
(&OnOff(_), _) => None,
342+
343+
(&OpenClosed(ref a), &OpenClosed(ref b)) => a.partial_cmp(b),
344+
(&OpenClosed(_), _) => None,
235345

236346
(&Duration(ref a), &Duration(ref b)) => a.partial_cmp(b),
237347
(&Duration(_), _) => None,
@@ -245,6 +355,9 @@ impl PartialOrd for Value {
245355
(&Color(ref a), &Color(ref b)) => a.partial_cmp(b),
246356
(&Color(_), _) => None,
247357

358+
(&ExtBool(ref a), &ExtBool(ref b)) => a.partial_cmp(b),
359+
(&ExtBool(_), _) => None,
360+
248361
(&ExtNumeric(ref a), &ExtNumeric(ref b)) => a.partial_cmp(b),
249362
(&ExtNumeric(_), _) => None,
250363

0 commit comments

Comments
 (0)