1pub mod node_cards;
4
5use node_cards::{NodeCards, NodeCard, Error as NodeCardsError};
6
7macro_rules! common_implementation {
8 ($name:ident, $ndp:expr, $bpc:expr) => {
9 paste::paste! {
10 common_implementation!($name, $ndp, $bpc, [<$name:camel Configuration>], [<$name:upper>]);
11 }
12 };
13 ($name:ident, $ndp:expr, $bpc:expr, $serde_name:ident, $human_name:ident) => {
14 paste::paste! {
15 common_implementation!($name, $ndp, $bpc, stringify!($serde_name), stringify!($human_name));
16 }
17 };
18 ($name:ident, $ndp:expr, $bpc:expr, $serde_name:expr, $human_name:expr) => {
19 mod $name {
20 use log::trace;
21 use crate::node_configuration::NodeConfiguration;
22 use crate::packet::{Data as PacketData, Error as PacketError};
23 use super::{NodeCards, NodeCard, NodeCardsError};
24 #[allow(unused_imports)]
25 use super::super::{NDP_USIC, NDP_SUSIC};
26
27 #[doc = concat!("Configuration for a (S)USIC node with ", $bpc, " bit cards.")]
28 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
29 pub struct Configuration {
30 pub(in super::super) transmit_delay: u16,
31 pub(in super::super) cards: NodeCards
32 }
33
34 impl Configuration {
35 const BPC: u8 = $bpc / 8;
37
38 #[doc = concat!("Create a new `", stringify!($name), "`.")]
39 #[doc = ""]
40 #[doc = "# Errors"]
41 #[doc = ""]
42 #[doc = "* [`NodeCardsError::CardAfterNone`] if there's an Input or Output card after a None card."]
43 #[doc = "* [`NodeCardsError::TooManyCards`] if there's more than 64 input/output cards."]
44 pub fn try_new(transmit_delay: u16, cards: &[NodeCard]) -> Result<Self, NodeCardsError> {
45 let cards = NodeCards::try_new(cards)?;
46 Ok(Self { transmit_delay, cards })
47 }
48
49 #[must_use]
51 pub fn cards(&self) -> &[NodeCard] {
52 self.cards.as_slice()
53 }
54
55 #[doc = concat!("Create a new `", stringify!($name), "` from raw bytes.")]
56 #[doc = ""]
57 #[doc = "# Errors"]
58 #[doc = ""]
59 #[doc = concat!("* [`PacketError::InvalidNodeType`] if the NDP byte isn't valid for a ", stringify!($name), " node.")]
60 #[doc = "* [`PacketError::InvalidConfiguration`]:"]
61 #[doc = " * [`NodeCardsError::InvalidCardType`] if there's an invalid card type in the card types sequence."]
62 #[doc = " * [`NodeCardsError::CardAfterNone`] if there's an Input or Output card after the first None card."]
63 #[doc = " * [`NodeCardsError::TooManyCards`] if there's more than 64 input/output cards."]
64 pub(in super::super) fn decode(raw: &[u8]) -> Result<Self, PacketError> {
65 trace!(concat!(stringify!($name), "::decode({:?})"), raw);
66 if raw[0] != $ndp {
67 return Err(PacketError::InvalidNodeType(raw[0]))
68 }
69
70 let mut cards = [NodeCard::None; 64];
71 for (index, &byte) in raw.iter().skip(4).enumerate() {
72 for i in 0..4 {
73 match (byte >> (2 * i)) & 0b11 {
74 0b00 => (),
75 0b01 => cards[(index * 4) + i] = NodeCard::Input,
76 0b10 => cards[(index * 4) + i] = NodeCard::Output,
77 _ => return Err(NodeCardsError::InvalidCardType.into())
78 }
79 }
80 }
81
82 Ok(Self::try_new(
83 u16::from_be_bytes([raw[1], raw[2]]),
84 &cards
85 )?)
86 }
87
88 pub(in super::super) fn encode(&self) -> PacketData {
89 trace!(concat!(stringify!($name), ".encode({:?})"), self);
90 let mut raw = PacketData::default();
91
92 raw.push($ndp).expect("Always pushes less than the maximum.");
93
94 let transmit_delay = self.transmit_delay.to_be_bytes();
95 raw.push(transmit_delay[0]).expect("Always pushes less than the maximum.");
96 raw.push(transmit_delay[1]).expect("Always pushes less than the maximum.");
97
98 let count_index = raw.len();
100 raw.push(0).expect("Always pushes less than the maximum.");
101
102 for chunk in self.cards.as_slice().chunks(4) {
103 let mut byte = 0;
104 for (i, &card) in chunk.iter().enumerate() {
105 byte |= (card as u8) << u8::try_from(2 * i).expect("Upto 64 cards * 2 = Upto 128, which is less than 255.");
106 }
107 if byte == 0 { break } raw[count_index] += 1;
109 raw.push(byte).expect("Always pushes less than the maximum.");
110 if byte & 0b1100_0000 == 0 { break } }
112
113 raw
114 }
115 }
116
117 impl NodeConfiguration for Configuration {
118 fn transmit_delay(&self) -> u16 { self.transmit_delay }
119 fn input_bytes(&self) -> u16 { u16::from(self.cards.input_cards()) * u16::from(Self::BPC) }
120 fn output_bytes(&self) -> u16 { u16::from(self.cards.output_cards()) * u16::from(Self::BPC) }
121 }
122
123 #[cfg(feature = "serde")]
124 #[cfg_attr(any(docsrs, toolchain = "nightly"), doc(cfg(feature = "serde")))]
125 #[cfg_attr(not(toolchain = "nightly"), doc = "**Available on crate feature serde only.**\n\n")]
126 impl ::serde::Serialize for Configuration {
127 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
128 use serde::ser::SerializeStruct;
129 let mut ser = serializer.serialize_struct($serde_name, 4)?;
130 ser.serialize_field("transmit_delay", &self.transmit_delay)?;
131 ser.serialize_field("cards", &self.cards)?;
132 ser.serialize_field("input_bytes", &self.input_bytes())?;
133 ser.serialize_field("output_bytes", &self.output_bytes())?;
134 ser.end()
135 }
136 }
137
138 #[cfg(feature = "serde")]
139 impl<'de> serde::de::Deserialize<'de> for Configuration {
140 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
141 struct Visitor;
142 impl<'de> serde::de::Visitor<'de> for Visitor {
143 type Value = Configuration;
144
145 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
146 write!(formatter, concat!("a ", $serde_name))
147 }
148
149 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {
150 let mut transmit_delay = None;
151 let mut cards: Option<NodeCards> = None;
152
153 while let Some(key) = map.next_key()? {
154 match key {
155 "transmit_delay" => {
156 if transmit_delay.is_some() {
157 return Err(serde::de::Error::duplicate_field("transmit_delay"));
158 }
159 transmit_delay = Some(map.next_value()?);
160 },
161 "cards" => {
162 if cards.is_some() {
163 return Err(serde::de::Error::duplicate_field("cards"));
164 }
165 cards = Some(map.next_value()?);
166 },
167 "input_bytes" | "output_bytes" => {
168 let _:u8 = map.next_value()?;
170 },
171 _ => {
172 return Err(serde::de::Error::unknown_field(key, &["transmit_delay, cards"]));
173 }
174 }
175 }
176
177 let transmit_delay = transmit_delay.unwrap_or_default();
178 let cards = cards.ok_or_else(|| serde::de::Error::missing_field("cards"))?;
179 Configuration::try_new(transmit_delay, cards.as_slice()).map_err(serde::de::Error::custom)
180 }
181 }
182
183 deserializer.deserialize_struct($serde_name, &["transmit_delay", "cards"], Visitor)
184 }
185 }
186 }
187 }
188}
189
190
191common_implementation!(usic, NDP_USIC, 24);
192pub use usic::Configuration as UsicConfiguration;
193common_implementation!(susic, NDP_SUSIC, 32);
194pub use susic::Configuration as SusicConfiguration;
195
196
197#[allow(clippy::missing_panics_doc, reason = "tests")]
198#[cfg(test)]
199mod tests {
200 use super::{UsicConfiguration, SusicConfiguration, NodeCards, NodeCard, NodeCardsError};
201 use crate::{packet::Error as PacketError, node_configuration::NodeConfiguration};
202
203 mod usic {
204 use super::*;
205
206 mod try_new {
207 use super::*;
208
209 #[test]
210 fn creates() {
211 let mut cards = [NodeCard::None; 64];
212 cards[0] = NodeCard::Input;
213 cards[1] = NodeCard::Output;
214 cards[2] = NodeCard::Output;
215
216 assert_eq!(
217 UsicConfiguration::try_new(10, &cards),
218 Ok(
219 UsicConfiguration {
220 transmit_delay: 10,
221 cards: NodeCards::try_new(&cards).unwrap()
222 }
223 )
224 );
225 }
226
227 #[test]
228 fn too_many_cards() {
229 let cards = [NodeCard::None; 65];
230 assert_eq!(
231 SusicConfiguration::try_new(0, &cards),
232 Err(NodeCardsError::TooManyCards)
233 );
234 }
235
236 #[test]
237 fn card_after_first_none() {
238 assert_eq!(
239 UsicConfiguration::try_new(0, &[NodeCard::None, NodeCard::Input]),
240 Err(NodeCardsError::CardAfterNone)
241 );
242 }
243 }
244
245 mod decode {
246 use super::*;
247
248 #[test]
249 fn nocards() {
250 let raw = [b'N', 0x01, 0xF4, 0];
251 assert_eq!(
252 UsicConfiguration::decode(&raw),
253 Ok(
254 UsicConfiguration {
255 transmit_delay: 500,
256 cards: NodeCards::default()
257 }
258 )
259 );
260 }
261
262 #[test]
263 fn cards_ioox() {
264 let raw = [b'N', 0, 0, 1, 0b0010_1001];
265 let mut cards = [NodeCard::None; 64];
266 cards[0] = NodeCard::Input;
267 cards[1] = NodeCard::Output;
268 cards[2] = NodeCard::Output;
269
270 assert_eq!(
271 UsicConfiguration::decode(&raw),
272 Ok(
273 UsicConfiguration {
274 transmit_delay: 0,
275 cards: NodeCards::try_new(&cards).unwrap()
276 }
277 )
278 );
279 }
280
281 #[test]
282 fn card_after_first_none() {
283 let raw = [b'N', 0, 0, 1, 0b1000_0000];
284 assert_eq!(
285 UsicConfiguration::decode(&raw),
286 Err(PacketError::InvalidConfiguration { source: NodeCardsError::CardAfterNone.into() })
287 );
288 }
289
290 #[test]
291 fn invalid_card_type() {
292 let raw = [b'N', 0, 0, 1, 0b0000_0011];
293 assert_eq!(
294 UsicConfiguration::decode(&raw),
295 Err(PacketError::InvalidConfiguration { source: NodeCardsError::InvalidCardType.into() })
296 );
297 }
298
299 #[test]
300 fn invalid_ndp() {
301 let raw = [b'Z', 0x01, 0x2C, 0];
302 let configuration = UsicConfiguration::decode(&raw);
303 assert_eq!(
304 configuration,
305 Err(PacketError::InvalidNodeType(90))
306 );
307 }
308 }
309
310 mod encode {
311 use super::*;
312
313 #[test]
314 fn nocards() {
315 let configuration = UsicConfiguration {
316 transmit_delay: 500,
317 cards: NodeCards::default()
318 };
319 assert_eq!(
320 configuration.encode(),
321 [b'N', 0x01, 0xF4, 0]
322 );
323 }
324
325 #[test]
326 fn cards_ioox() {
327 let mut cards = [NodeCard::None; 64];
328 cards[0] = NodeCard::Input;
329 cards[1] = NodeCard::Output;
330 cards[2] = NodeCard::Output;
331
332 let configuration = UsicConfiguration {
333 transmit_delay: 0,
334 cards: NodeCards::try_new(&cards).unwrap()
335 };
336
337 assert_eq!(
338 configuration.encode(),
339 [b'N', 0, 0, 1, 0b0010_1001]
340 );
341 }
342 }
343
344 #[test]
345 fn node_configuration() {
346 let configuration = UsicConfiguration::try_new(
347 200,
348 &[NodeCard::Input, NodeCard::Output, NodeCard::Output],
349 ).unwrap();
350
351 assert_eq!(configuration.transmit_delay(), 200);
352 assert_eq!(configuration.input_bytes(), 3);
353 assert_eq!(configuration.output_bytes(), 6);
354 }
355
356 #[test]
357 fn cards() {
358 let cards = NodeCards::try_new(&[NodeCard::Input]).unwrap();
359 let configuration = UsicConfiguration::try_new(0, cards.as_slice()).unwrap();
360 assert_eq!(configuration.cards(), cards.as_slice());
361 }
362
363 #[cfg(feature = "serde")]
364 mod serde {
365 use super::*;
366 use serde_test::{assert_tokens, assert_de_tokens, assert_de_tokens_error, Token};
367
368 #[test]
369 fn valid() {
370 let configuration = UsicConfiguration::try_new(
371 1,
372 &[NodeCard::Output, NodeCard::Output, NodeCard::Input]
373 ).unwrap();
374
375 assert_tokens(
376 &configuration,
377 &[
378 Token::Struct { name: "UsicConfiguration", len: 4 },
379 Token::BorrowedStr("transmit_delay"),
380 Token::U16(1),
381 Token::BorrowedStr("cards"),
382 Token::Seq { len: None },
383 Token::UnitVariant { name: "NodeCard", variant: "Output" },
384 Token::UnitVariant { name: "NodeCard", variant: "Output" },
385 Token::UnitVariant { name: "NodeCard", variant: "Input" },
386 Token::SeqEnd,
387 Token::BorrowedStr("input_bytes"),
388 Token::U16(3),
389 Token::BorrowedStr("output_bytes"),
390 Token::U16(6),
391 Token::StructEnd
392 ]
393 );
394 }
395
396 #[test]
397 fn ignored_fields_for_deserialize() {
398 let configuration = UsicConfiguration::try_new(
400 1,
401 &[NodeCard::Output, NodeCard::Output, NodeCard::Input]
402 ).unwrap();
403
404 assert_de_tokens(
405 &configuration,
406 &[
407 Token::Struct { name: "UsicConfiguration", len: 4 },
408 Token::BorrowedStr("transmit_delay"),
409 Token::U16(1),
410 Token::BorrowedStr("cards"),
411 Token::Seq { len: None },
412 Token::UnitVariant { name: "NodeCard", variant: "Output" },
413 Token::UnitVariant { name: "NodeCard", variant: "Output" },
414 Token::UnitVariant { name: "NodeCard", variant: "Input" },
415 Token::SeqEnd,
416 Token::BorrowedStr("input_bytes"),
417 Token::U16(0),
418 Token::BorrowedStr("output_bytes"),
419 Token::U16(0),
420 Token::StructEnd
421 ]
422 );
423 }
424
425 mod optional_fields_for_deserialize {
426 use super::*;
427
428 #[test]
429 fn transmit_delay() { let configuration = UsicConfiguration::try_new(
431 0,
432 &[]
433 ).unwrap();
434
435 assert_de_tokens(
436 &configuration,
437 &[
438 Token::Struct { name: "UsicConfiguration", len: 4 },
439 Token::BorrowedStr("cards"),
440 Token::Seq { len: None },
441 Token::SeqEnd,
442 Token::StructEnd
443 ]
444 );
445 }
446 }
447
448 #[test]
449 fn too_many_cards() {
450 assert_de_tokens_error::<UsicConfiguration>(
451 &[
452 Token::Struct { name: "UsicConfiguration", len: 1 },
453 Token::BorrowedStr("cards"),
454 Token::Seq { len: None },
455 Token::UnitVariant { name: "NodeCard", variant: "Output" },
457 Token::UnitVariant { name: "NodeCard", variant: "Output" },
458 Token::UnitVariant { name: "NodeCard", variant: "Output" },
459 Token::UnitVariant { name: "NodeCard", variant: "Output" },
460 Token::UnitVariant { name: "NodeCard", variant: "Output" },
461 Token::UnitVariant { name: "NodeCard", variant: "Output" },
462 Token::UnitVariant { name: "NodeCard", variant: "Output" },
463 Token::UnitVariant { name: "NodeCard", variant: "Output" },
464 Token::UnitVariant { name: "NodeCard", variant: "Output" },
465 Token::UnitVariant { name: "NodeCard", variant: "Output" },
466 Token::UnitVariant { name: "NodeCard", variant: "Output" },
467 Token::UnitVariant { name: "NodeCard", variant: "Output" },
468 Token::UnitVariant { name: "NodeCard", variant: "Output" },
469 Token::UnitVariant { name: "NodeCard", variant: "Output" },
470 Token::UnitVariant { name: "NodeCard", variant: "Output" },
471 Token::UnitVariant { name: "NodeCard", variant: "Output" },
472 Token::UnitVariant { name: "NodeCard", variant: "Output" },
473 Token::UnitVariant { name: "NodeCard", variant: "Output" },
474 Token::UnitVariant { name: "NodeCard", variant: "Output" },
475 Token::UnitVariant { name: "NodeCard", variant: "Output" },
476 Token::UnitVariant { name: "NodeCard", variant: "Output" },
477 Token::UnitVariant { name: "NodeCard", variant: "Output" },
478 Token::UnitVariant { name: "NodeCard", variant: "Output" },
479 Token::UnitVariant { name: "NodeCard", variant: "Output" },
480 Token::UnitVariant { name: "NodeCard", variant: "Output" },
481 Token::UnitVariant { name: "NodeCard", variant: "Output" },
482 Token::UnitVariant { name: "NodeCard", variant: "Output" },
483 Token::UnitVariant { name: "NodeCard", variant: "Output" },
484 Token::UnitVariant { name: "NodeCard", variant: "Output" },
485 Token::UnitVariant { name: "NodeCard", variant: "Output" },
486 Token::UnitVariant { name: "NodeCard", variant: "Output" },
487 Token::UnitVariant { name: "NodeCard", variant: "Output" },
488 Token::UnitVariant { name: "NodeCard", variant: "Output" },
489 Token::UnitVariant { name: "NodeCard", variant: "Output" },
490 Token::UnitVariant { name: "NodeCard", variant: "Output" },
491 Token::UnitVariant { name: "NodeCard", variant: "Output" },
492 Token::UnitVariant { name: "NodeCard", variant: "Output" },
493 Token::UnitVariant { name: "NodeCard", variant: "Output" },
494 Token::UnitVariant { name: "NodeCard", variant: "Output" },
495 Token::UnitVariant { name: "NodeCard", variant: "Output" },
496 Token::UnitVariant { name: "NodeCard", variant: "Output" },
497 Token::UnitVariant { name: "NodeCard", variant: "Output" },
498 Token::UnitVariant { name: "NodeCard", variant: "Output" },
499 Token::UnitVariant { name: "NodeCard", variant: "Output" },
500 Token::UnitVariant { name: "NodeCard", variant: "Output" },
501 Token::UnitVariant { name: "NodeCard", variant: "Output" },
502 Token::UnitVariant { name: "NodeCard", variant: "Output" },
503 Token::UnitVariant { name: "NodeCard", variant: "Output" },
504 Token::UnitVariant { name: "NodeCard", variant: "Output" },
505 Token::UnitVariant { name: "NodeCard", variant: "Output" },
506 Token::UnitVariant { name: "NodeCard", variant: "Output" },
507 Token::UnitVariant { name: "NodeCard", variant: "Output" },
508 Token::UnitVariant { name: "NodeCard", variant: "Output" },
509 Token::UnitVariant { name: "NodeCard", variant: "Output" },
510 Token::UnitVariant { name: "NodeCard", variant: "Output" },
511 Token::UnitVariant { name: "NodeCard", variant: "Output" },
512 Token::UnitVariant { name: "NodeCard", variant: "Output" },
513 Token::UnitVariant { name: "NodeCard", variant: "Output" },
514 Token::UnitVariant { name: "NodeCard", variant: "Output" },
515 Token::UnitVariant { name: "NodeCard", variant: "Output" },
516 Token::UnitVariant { name: "NodeCard", variant: "Output" },
517 Token::UnitVariant { name: "NodeCard", variant: "Output" },
518 Token::UnitVariant { name: "NodeCard", variant: "Output" },
519 Token::UnitVariant { name: "NodeCard", variant: "Output" },
520 Token::UnitVariant { name: "NodeCard", variant: "Output" },
521 Token::SeqEnd
522 ],
523 "invalid length 65, expected no more than 64 cards"
524 );
525
526 assert_de_tokens_error::<UsicConfiguration>(
527 &[
528 Token::Struct { name: "UsicConfiguration", len: 1 },
529 Token::BorrowedStr("cards"),
530 Token::Seq { len: Some(65) },
531 ],
532 "invalid length 65, expected no more than 64 cards"
533 );
534 }
535
536 #[test]
537 fn card_after_first_none() {
538 assert_de_tokens_error::<UsicConfiguration>(
539 &[
540 Token::Struct { name: "UsicConfiguration", len: 1 },
541 Token::BorrowedStr("cards"),
542 Token::Seq { len: None },
543 Token::UnitVariant { name: "NodeCard", variant: "None" },
544 Token::UnitVariant { name: "NodeCard", variant: "Output" },
545 Token::SeqEnd
546 ],
547 "expected no cards after the first none"
548 );
549 }
550 }
551 }
552
553 mod susic {
554 use super::*;
555
556 mod try_new {
557 use super::*;
558
559 #[test]
560 fn creates() {
561 let mut cards = [NodeCard::None; 64];
562 cards[0] = NodeCard::Input;
563 cards[1] = NodeCard::Input;
564 cards[2] = NodeCard::Output;
565
566 assert_eq!(
567 SusicConfiguration::try_new(10, &cards),
568 Ok(
569 SusicConfiguration {
570 transmit_delay: 10,
571 cards: NodeCards::try_new(&cards).unwrap()
572 }
573 )
574 );
575 }
576
577 #[test]
578 fn too_many_cards() {
579 let cards = [NodeCard::None; 65];
580 assert_eq!(
581 SusicConfiguration::try_new(0, &cards),
582 Err(NodeCardsError::TooManyCards)
583 );
584 }
585
586 #[test]
587 fn card_after_first_none() {
588 assert_eq!(
589 SusicConfiguration::try_new(0, &[NodeCard::None, NodeCard::Input]),
590 Err(NodeCardsError::CardAfterNone)
591 );
592 }
593 }
594
595 mod decode {
596 use super::*;
597
598 #[test]
599 fn nocards() {
600 let raw = [b'X', 0x01, 0xF4, 0];
601 assert_eq!(
602 SusicConfiguration::decode(&raw),
603 Ok(
604 SusicConfiguration {
605 transmit_delay: 500,
606 cards: NodeCards::default()
607 }
608 )
609 );
610 }
611
612 #[test]
613 fn cards_ioox() {
614 let raw = [b'X', 0, 0, 1, 0b0010_1001];
615 let mut cards = [NodeCard::None; 64];
616 cards[0] = NodeCard::Input;
617 cards[1] = NodeCard::Output;
618 cards[2] = NodeCard::Output;
619
620 assert_eq!(
621 SusicConfiguration::decode(&raw),
622 Ok(
623 SusicConfiguration {
624 transmit_delay: 0,
625 cards: NodeCards::try_new(&cards).unwrap()
626 }
627 )
628 );
629 }
630
631 #[test]
632 fn card_after_first_none() {
633 let raw = [b'X', 0, 0, 1, 0b1000_0000];
634 assert_eq!(
635 SusicConfiguration::decode(&raw),
636 Err(PacketError::InvalidConfiguration { source: NodeCardsError::CardAfterNone.into() })
637 );
638 }
639
640 #[test]
641 fn invalid_card_type() {
642 let raw = [b'X', 0, 0, 1, 0b0000_0011];
643 assert_eq!(
644 SusicConfiguration::decode(&raw),
645 Err(PacketError::InvalidConfiguration { source: NodeCardsError::InvalidCardType.into() })
646 );
647 }
648
649
650 #[test]
651 fn invalid_ndp() {
652 let raw = [b'Z', 0x01, 0x2C, 0];
653 let configuration = SusicConfiguration::decode(&raw);
654 assert_eq!(
655 configuration,
656 Err(PacketError::InvalidNodeType(90))
657 );
658 }
659 }
660
661 mod encode {
662 use super::*;
663
664 #[test]
665 fn nocards() {
666 let configuration = SusicConfiguration {
667 transmit_delay: 500,
668 cards: NodeCards::default()
669 };
670 assert_eq!(
671 configuration.encode(),
672 [b'X', 0x01, 0xF4, 0]
673 );
674 }
675
676 #[test]
677 fn cards_ioox() {
678 let mut cards = [NodeCard::None; 64];
679 cards[0] = NodeCard::Input;
680 cards[1] = NodeCard::Output;
681 cards[2] = NodeCard::Output;
682
683 let configuration = SusicConfiguration {
684 transmit_delay: 0,
685 cards: NodeCards::try_new(&cards).unwrap()
686 };
687
688 assert_eq!(
689 configuration.encode(),
690 [b'X', 0, 0, 1, 0b0010_1001]
691 );
692 }
693 }
694
695 #[test]
696 fn node_configuration() {
697 let configuration = SusicConfiguration::try_new(
698 200,
699 &[NodeCard::Input, NodeCard::Output, NodeCard::Output]
700 ).unwrap();
701
702 assert_eq!(configuration.transmit_delay(), 200);
703 assert_eq!(configuration.input_bytes(), 4);
704 assert_eq!(configuration.output_bytes(), 8);
705 }
706
707 #[test]
708 fn cards() {
709 let cards = NodeCards::try_new(&[NodeCard::Output]).unwrap();
710 let configuration = UsicConfiguration::try_new(0, cards.as_slice()).unwrap();
711 assert_eq!(configuration.cards(), cards.as_slice());
712 }
713
714 #[cfg(feature = "serde")]
715 mod serde {
716 use super::*;
717 use serde_test::{assert_tokens, assert_de_tokens, assert_de_tokens_error, Token};
718
719 #[test]
720 fn valid() {
721 let configuration = SusicConfiguration::try_new(
722 1,
723 &[NodeCard::Output, NodeCard::Output, NodeCard::Input]
724 ).unwrap();
725
726 assert_tokens(
727 &configuration,
728 &[
729 Token::Struct { name: "SusicConfiguration", len: 4 },
730 Token::BorrowedStr("transmit_delay"),
731 Token::U16(1),
732 Token::BorrowedStr("cards"),
733 Token::Seq { len: None },
734 Token::UnitVariant { name: "NodeCard", variant: "Output" },
735 Token::UnitVariant { name: "NodeCard", variant: "Output" },
736 Token::UnitVariant { name: "NodeCard", variant: "Input" },
737 Token::SeqEnd,
738 Token::BorrowedStr("input_bytes"),
739 Token::U16(4),
740 Token::BorrowedStr("output_bytes"),
741 Token::U16(8),
742 Token::StructEnd
743 ]
744 );
745 }
746
747 #[test]
748 fn ignored_fields_for_deserialize() {
749 let configuration = SusicConfiguration::try_new(
751 1,
752 &[NodeCard::Output, NodeCard::Output, NodeCard::Input]
753 ).unwrap();
754
755 assert_de_tokens(
756 &configuration,
757 &[
758 Token::Struct { name: "SusicConfiguration", len: 4 },
759 Token::BorrowedStr("transmit_delay"),
760 Token::U16(1),
761 Token::BorrowedStr("cards"),
762 Token::Seq { len: None },
763 Token::UnitVariant { name: "NodeCard", variant: "Output" },
764 Token::UnitVariant { name: "NodeCard", variant: "Output" },
765 Token::UnitVariant { name: "NodeCard", variant: "Input" },
766 Token::SeqEnd,
767 Token::BorrowedStr("input_bytes"),
768 Token::U16(0),
769 Token::BorrowedStr("output_bytes"),
770 Token::U16(0),
771 Token::StructEnd
772 ]
773 );
774 }
775
776 mod optional_fields_for_deserialize {
777 use super::*;
778
779 #[test]
780 fn transmit_delay() { let configuration = UsicConfiguration::try_new(
782 0,
783 &[]
784 ).unwrap();
785
786 assert_de_tokens(
787 &configuration,
788 &[
789 Token::Struct { name: "UsicConfiguration", len: 4 },
790 Token::BorrowedStr("cards"),
791 Token::Seq { len: None },
792 Token::SeqEnd,
793 Token::StructEnd
794 ]
795 );
796 }
797 }
798
799 #[test]
800 fn too_many_cards() {
801 assert_de_tokens_error::<SusicConfiguration>(
802 &[
803 Token::Struct { name: "SusicConfiguration", len: 1 },
804 Token::BorrowedStr("cards"),
805 Token::Seq { len: None },
806 Token::UnitVariant { name: "NodeCard", variant: "Output" },
808 Token::UnitVariant { name: "NodeCard", variant: "Output" },
809 Token::UnitVariant { name: "NodeCard", variant: "Output" },
810 Token::UnitVariant { name: "NodeCard", variant: "Output" },
811 Token::UnitVariant { name: "NodeCard", variant: "Output" },
812 Token::UnitVariant { name: "NodeCard", variant: "Output" },
813 Token::UnitVariant { name: "NodeCard", variant: "Output" },
814 Token::UnitVariant { name: "NodeCard", variant: "Output" },
815 Token::UnitVariant { name: "NodeCard", variant: "Output" },
816 Token::UnitVariant { name: "NodeCard", variant: "Output" },
817 Token::UnitVariant { name: "NodeCard", variant: "Output" },
818 Token::UnitVariant { name: "NodeCard", variant: "Output" },
819 Token::UnitVariant { name: "NodeCard", variant: "Output" },
820 Token::UnitVariant { name: "NodeCard", variant: "Output" },
821 Token::UnitVariant { name: "NodeCard", variant: "Output" },
822 Token::UnitVariant { name: "NodeCard", variant: "Output" },
823 Token::UnitVariant { name: "NodeCard", variant: "Output" },
824 Token::UnitVariant { name: "NodeCard", variant: "Output" },
825 Token::UnitVariant { name: "NodeCard", variant: "Output" },
826 Token::UnitVariant { name: "NodeCard", variant: "Output" },
827 Token::UnitVariant { name: "NodeCard", variant: "Output" },
828 Token::UnitVariant { name: "NodeCard", variant: "Output" },
829 Token::UnitVariant { name: "NodeCard", variant: "Output" },
830 Token::UnitVariant { name: "NodeCard", variant: "Output" },
831 Token::UnitVariant { name: "NodeCard", variant: "Output" },
832 Token::UnitVariant { name: "NodeCard", variant: "Output" },
833 Token::UnitVariant { name: "NodeCard", variant: "Output" },
834 Token::UnitVariant { name: "NodeCard", variant: "Output" },
835 Token::UnitVariant { name: "NodeCard", variant: "Output" },
836 Token::UnitVariant { name: "NodeCard", variant: "Output" },
837 Token::UnitVariant { name: "NodeCard", variant: "Output" },
838 Token::UnitVariant { name: "NodeCard", variant: "Output" },
839 Token::UnitVariant { name: "NodeCard", variant: "Output" },
840 Token::UnitVariant { name: "NodeCard", variant: "Output" },
841 Token::UnitVariant { name: "NodeCard", variant: "Output" },
842 Token::UnitVariant { name: "NodeCard", variant: "Output" },
843 Token::UnitVariant { name: "NodeCard", variant: "Output" },
844 Token::UnitVariant { name: "NodeCard", variant: "Output" },
845 Token::UnitVariant { name: "NodeCard", variant: "Output" },
846 Token::UnitVariant { name: "NodeCard", variant: "Output" },
847 Token::UnitVariant { name: "NodeCard", variant: "Output" },
848 Token::UnitVariant { name: "NodeCard", variant: "Output" },
849 Token::UnitVariant { name: "NodeCard", variant: "Output" },
850 Token::UnitVariant { name: "NodeCard", variant: "Output" },
851 Token::UnitVariant { name: "NodeCard", variant: "Output" },
852 Token::UnitVariant { name: "NodeCard", variant: "Output" },
853 Token::UnitVariant { name: "NodeCard", variant: "Output" },
854 Token::UnitVariant { name: "NodeCard", variant: "Output" },
855 Token::UnitVariant { name: "NodeCard", variant: "Output" },
856 Token::UnitVariant { name: "NodeCard", variant: "Output" },
857 Token::UnitVariant { name: "NodeCard", variant: "Output" },
858 Token::UnitVariant { name: "NodeCard", variant: "Output" },
859 Token::UnitVariant { name: "NodeCard", variant: "Output" },
860 Token::UnitVariant { name: "NodeCard", variant: "Output" },
861 Token::UnitVariant { name: "NodeCard", variant: "Output" },
862 Token::UnitVariant { name: "NodeCard", variant: "Output" },
863 Token::UnitVariant { name: "NodeCard", variant: "Output" },
864 Token::UnitVariant { name: "NodeCard", variant: "Output" },
865 Token::UnitVariant { name: "NodeCard", variant: "Output" },
866 Token::UnitVariant { name: "NodeCard", variant: "Output" },
867 Token::UnitVariant { name: "NodeCard", variant: "Output" },
868 Token::UnitVariant { name: "NodeCard", variant: "Output" },
869 Token::UnitVariant { name: "NodeCard", variant: "Output" },
870 Token::UnitVariant { name: "NodeCard", variant: "Output" },
871 Token::UnitVariant { name: "NodeCard", variant: "Output" },
872 Token::SeqEnd
873 ],
874 "invalid length 65, expected no more than 64 cards"
875 );
876
877 assert_de_tokens_error::<SusicConfiguration>(
878 &[
879 Token::Struct { name: "SusicConfiguration", len: 1 },
880 Token::BorrowedStr("cards"),
881 Token::Seq { len: Some(65) },
882 ],
883 "invalid length 65, expected no more than 64 cards"
884 );
885 }
886
887 #[test]
888 fn card_after_first_none() {
889 assert_de_tokens_error::<SusicConfiguration>(
890 &[
891 Token::Struct { name: "SusicConfiguration", len: 1 },
892 Token::BorrowedStr("cards"),
893 Token::Seq { len: None },
894 Token::UnitVariant { name: "NodeCard", variant: "None" },
895 Token::UnitVariant { name: "NodeCard", variant: "Output" },
896 Token::SeqEnd
897 ],
898 "expected no cards after the first none"
899 );
900 }
901 }
902 }
903}