|
@@ -26,6 +26,23 @@ impl Parse for Protocol {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl Protocol {
|
|
|
+ pub(crate) fn new(
|
|
|
+ name_def: NameDef,
|
|
|
+ states_def: StatesDef,
|
|
|
+ transitions: impl IntoIterator<Item = Transition>,
|
|
|
+ ) -> Self {
|
|
|
+ let mut transitions: Punctuated<Transition, Token![;]> = transitions.into_iter().collect();
|
|
|
+ transitions.push_punct(Token));
|
|
|
+ Self {
|
|
|
+ name_def,
|
|
|
+ states_def,
|
|
|
+ transitions,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl GetSpan for Protocol {
|
|
|
fn span(&self) -> Span {
|
|
|
self.name_def
|
|
@@ -49,6 +66,19 @@ impl NameDef {
|
|
|
const NAME_IDENT_ERR: &str = "invalid name declaration identifier";
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl NameDef {
|
|
|
+ pub(crate) fn new(name: &str) -> Self {
|
|
|
+ Self {
|
|
|
+ let_token: Token),
|
|
|
+ name_ident: new_ident("name"),
|
|
|
+ eq_token: Token),
|
|
|
+ name: new_ident(name),
|
|
|
+ semi_token: Token),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for NameDef {
|
|
|
/// name_def : "let" "name" '=' Ident ';' ;
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -83,6 +113,15 @@ impl StatesDef {
|
|
|
const ARRAY_IDENT_ERR: &str = "invalid states array identifier. Expected 'states'.";
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl StatesDef {
|
|
|
+ pub(crate) fn new(state_names: impl IntoIterator<Item = &'static str>) -> Self {
|
|
|
+ Self {
|
|
|
+ states: IdentArray::new(state_names),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for StatesDef {
|
|
|
/// states_def : "let" "states" '=' ident_array ';' ;
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -117,6 +156,13 @@ impl IdentArray {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl IdentArray {
|
|
|
+ pub(crate) fn new(state_names: impl IntoIterator<Item = &'static str>) -> Self {
|
|
|
+ Self(state_names.into_iter().map(new_ident).collect())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl GetSpan for IdentArray {
|
|
|
fn span(&self) -> Span {
|
|
|
self.0.span()
|
|
@@ -152,6 +198,31 @@ pub(crate) struct Transition {
|
|
|
pub(crate) out_msgs: DestList,
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl Transition {
|
|
|
+ pub(crate) fn new(
|
|
|
+ in_state: State,
|
|
|
+ in_msg: Option<Message>,
|
|
|
+ out_states: impl IntoIterator<Item = State>,
|
|
|
+ out_msgs: impl IntoIterator<Item = Dest>,
|
|
|
+ ) -> Self {
|
|
|
+ let out_msgs = DestList(out_msgs.into_iter().collect());
|
|
|
+ let redirect = if out_msgs.as_ref().is_empty() {
|
|
|
+ None
|
|
|
+ } else {
|
|
|
+ Some(Token))
|
|
|
+ };
|
|
|
+ Self {
|
|
|
+ in_state,
|
|
|
+ in_msg,
|
|
|
+ arrow: Token),
|
|
|
+ out_states: StatesList(out_states.into_iter().collect()),
|
|
|
+ redirect,
|
|
|
+ out_msgs,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for Transition {
|
|
|
/// transition : state ( '?' message )? "->" states_list ( '>' dest_list )? ;
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -198,6 +269,23 @@ pub(crate) struct State {
|
|
|
pub(crate) owned_states: IdentArray,
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl State {
|
|
|
+ pub(crate) fn new(
|
|
|
+ state_trait: &str,
|
|
|
+ owned_states: impl IntoIterator<Item = &'static str>,
|
|
|
+ ) -> Self {
|
|
|
+ Self {
|
|
|
+ state_trait: new_ident(state_trait),
|
|
|
+ owned_states: IdentArray::new(owned_states),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn new_empty_owned(state_trait: &str) -> Self {
|
|
|
+ Self::new(state_trait, std::iter::empty())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for State {
|
|
|
/// state : Ident ident_array? ;
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -297,6 +385,13 @@ pub(crate) struct Dest {
|
|
|
pub(crate) msg: Message,
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl Dest {
|
|
|
+ pub(crate) fn new(state: DestinationState, msg: Message) -> Self {
|
|
|
+ Self { state, msg }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for Dest {
|
|
|
/// dest : dest_state '!' message
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -387,6 +482,32 @@ impl Message {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
+impl Message {
|
|
|
+ pub(crate) fn new(
|
|
|
+ msg_type: &str,
|
|
|
+ is_reply: bool,
|
|
|
+ owned_states: impl IntoIterator<Item = &'static str>,
|
|
|
+ ) -> Self {
|
|
|
+ let (reply_part, ident_field) = if is_reply {
|
|
|
+ let reply_part = MessageReplyPart {
|
|
|
+ colons: Token),
|
|
|
+ reply: new_ident(MessageReplyPart::REPLY_IDENT),
|
|
|
+ };
|
|
|
+ let variant = format_ident!("{}{}", msg_type, MessageReplyPart::REPLY_IDENT);
|
|
|
+ (Some(reply_part), Some(variant))
|
|
|
+ } else {
|
|
|
+ (None, None)
|
|
|
+ };
|
|
|
+ Self {
|
|
|
+ msg_type: new_ident(msg_type),
|
|
|
+ reply_part,
|
|
|
+ owned_states: IdentArray::new(owned_states),
|
|
|
+ ident: ident_field,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Parse for Message {
|
|
|
/// message : Ident ( "::" "Reply" )? ident_array? ;
|
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
@@ -516,33 +637,17 @@ impl<R: GetSpan> LeftJoin<Option<R>> for Span {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/// Returns a new span whose text content is the given string and whose span is `Span::call_site`.
|
|
|
+#[cfg(test)]
|
|
|
+pub(crate) fn new_ident(str: &str) -> Ident {
|
|
|
+ Ident::new(str, Span::call_site())
|
|
|
+}
|
|
|
+
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
use super::*;
|
|
|
- use proc_macro2::Span;
|
|
|
- use std::iter::{self, IntoIterator};
|
|
|
use syn::parse_str;
|
|
|
|
|
|
- fn ident(str: &str) -> Ident {
|
|
|
- Ident::new(str, Span::call_site())
|
|
|
- }
|
|
|
-
|
|
|
- impl Protocol {
|
|
|
- fn new(
|
|
|
- name_def: NameDef,
|
|
|
- states_def: StatesDef,
|
|
|
- transitions: impl Iterator<Item = Transition>,
|
|
|
- ) -> Self {
|
|
|
- let mut transitions: Punctuated<Transition, Token![;]> = transitions.collect();
|
|
|
- transitions.push_punct(Token));
|
|
|
- Self {
|
|
|
- name_def,
|
|
|
- states_def,
|
|
|
- transitions,
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn protocol_parse_minimal() {
|
|
|
const EXPECTED_NAME: &str = "Foo";
|
|
@@ -560,22 +665,21 @@ let states = [{}];
|
|
|
);
|
|
|
let expected = Protocol::new(
|
|
|
NameDef::new(EXPECTED_NAME),
|
|
|
- StatesDef::new(EXPECTED_STATES.into_iter()),
|
|
|
+ StatesDef::new(EXPECTED_STATES),
|
|
|
[
|
|
|
Transition::new(
|
|
|
- State::new(EXPECTED_STATES[0], iter::empty()),
|
|
|
+ State::new(EXPECTED_STATES[0], []),
|
|
|
None,
|
|
|
- [State::new(EXPECTED_STATES[1], iter::empty())].into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ [State::new(EXPECTED_STATES[1], [])],
|
|
|
+ [],
|
|
|
),
|
|
|
Transition::new(
|
|
|
- State::new(EXPECTED_STATES[1], iter::empty()),
|
|
|
+ State::new(EXPECTED_STATES[1], []),
|
|
|
None,
|
|
|
- [State::new(EXPECTED_STATES[2], iter::empty())].into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ [State::new(EXPECTED_STATES[2], [])],
|
|
|
+ [],
|
|
|
),
|
|
|
- ]
|
|
|
- .into_iter(),
|
|
|
+ ],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Protocol>(&input).unwrap();
|
|
@@ -583,18 +687,6 @@ let states = [{}];
|
|
|
assert_eq!(expected, actual);
|
|
|
}
|
|
|
|
|
|
- impl NameDef {
|
|
|
- fn new(name: &str) -> Self {
|
|
|
- Self {
|
|
|
- let_token: Token),
|
|
|
- name_ident: ident("name"),
|
|
|
- eq_token: Token),
|
|
|
- name: ident(name),
|
|
|
- semi_token: Token),
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn name_def_parse() {
|
|
|
const EXPECTED_NAME: &str = "Foofercorg";
|
|
@@ -615,19 +707,11 @@ let states = [{}];
|
|
|
assert_eq!(NameDef::NAME_IDENT_ERR, err_str);
|
|
|
}
|
|
|
|
|
|
- impl StatesDef {
|
|
|
- fn new(state_names: impl Iterator<Item = &'static str>) -> Self {
|
|
|
- Self {
|
|
|
- states: IdentArray::new(state_names),
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn states_def_parse() {
|
|
|
const EXPECTED_STATES: [&str; 2] = ["First", "Second"];
|
|
|
let input = format!("let states = [{}];", EXPECTED_STATES.join(", "));
|
|
|
- let expected = StatesDef::new(EXPECTED_STATES.into_iter());
|
|
|
+ let expected = StatesDef::new(EXPECTED_STATES);
|
|
|
|
|
|
let actual = parse_str::<StatesDef>(&input).unwrap();
|
|
|
|
|
@@ -643,17 +727,11 @@ let states = [{}];
|
|
|
assert_eq!(StatesDef::ARRAY_IDENT_ERR, err_str);
|
|
|
}
|
|
|
|
|
|
- impl IdentArray {
|
|
|
- fn new(state_names: impl Iterator<Item = &'static str>) -> Self {
|
|
|
- Self(state_names.map(ident).collect())
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn ident_array_new() {
|
|
|
const EXPECTED: [&str; 2] = ["Red", "Green"];
|
|
|
|
|
|
- let actual = IdentArray::new(EXPECTED.into_iter());
|
|
|
+ let actual = IdentArray::new(EXPECTED);
|
|
|
|
|
|
assert_eq!(EXPECTED.len(), actual.0.len());
|
|
|
assert_eq!(actual.0[0], EXPECTED[0]);
|
|
@@ -662,18 +740,18 @@ let states = [{}];
|
|
|
|
|
|
#[test]
|
|
|
fn ident_array_not_equal() {
|
|
|
- let expected = IdentArray::new(["Red", "Green"].into_iter());
|
|
|
+ let expected = IdentArray::new(["Red", "Green"]);
|
|
|
|
|
|
- let actual = IdentArray::new(["Blue", "Gold"].into_iter());
|
|
|
+ let actual = IdentArray::new(["Blue", "Gold"]);
|
|
|
|
|
|
assert_ne!(expected, actual);
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
fn ident_array_not_equal_different_lens() {
|
|
|
- let expected = IdentArray::new(["Red", "Green"].into_iter());
|
|
|
+ let expected = IdentArray::new(["Red", "Green"]);
|
|
|
|
|
|
- let actual = IdentArray::new(["Red"].into_iter());
|
|
|
+ let actual = IdentArray::new(["Red"]);
|
|
|
|
|
|
assert_ne!(expected, actual);
|
|
|
}
|
|
@@ -682,7 +760,7 @@ let states = [{}];
|
|
|
fn ident_array_parse() {
|
|
|
const EXPECTED_STATES: [&str; 2] = ["Sad", "Glad"];
|
|
|
let input = format!("[{}, {}]", EXPECTED_STATES[0], EXPECTED_STATES[1]);
|
|
|
- let expected = IdentArray::new(EXPECTED_STATES.into_iter());
|
|
|
+ let expected = IdentArray::new(EXPECTED_STATES);
|
|
|
|
|
|
let actual = parse_str::<IdentArray>(&input).unwrap();
|
|
|
|
|
@@ -698,40 +776,16 @@ let states = [{}];
|
|
|
assert_eq!(IdentArray::EMPTY_ERR, err_str);
|
|
|
}
|
|
|
|
|
|
- impl Transition {
|
|
|
- fn new(
|
|
|
- in_state: State,
|
|
|
- in_msg: Option<Message>,
|
|
|
- out_states: impl Iterator<Item = State>,
|
|
|
- out_msgs: impl Iterator<Item = Dest>,
|
|
|
- ) -> Self {
|
|
|
- let out_msgs = DestList(out_msgs.collect());
|
|
|
- let redirect = if out_msgs.as_ref().is_empty() {
|
|
|
- None
|
|
|
- } else {
|
|
|
- Some(Token))
|
|
|
- };
|
|
|
- Self {
|
|
|
- in_state,
|
|
|
- in_msg,
|
|
|
- arrow: Token),
|
|
|
- out_states: StatesList(out_states.collect()),
|
|
|
- redirect,
|
|
|
- out_msgs,
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn transition_parse_minimal() {
|
|
|
const EXPECTED_IN_STATE: &str = "Catcher";
|
|
|
const EXPECTED_OUT_STATE: &str = "End";
|
|
|
let input = format!("{EXPECTED_IN_STATE} -> {EXPECTED_OUT_STATE}");
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
None,
|
|
|
- [EXPECTED_OUT_STATE].map(State::new_empty_owned).into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ [EXPECTED_OUT_STATE].map(State::new_empty_owned),
|
|
|
+ [],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -746,10 +800,10 @@ let states = [{}];
|
|
|
const EXPECTED_OUT_STATE: &str = "End";
|
|
|
let input = format!("{EXPECTED_IN_STATE}?{EXPECTED_IN_MSG} -> {EXPECTED_OUT_STATE}");
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
- Some(Message::new(EXPECTED_IN_MSG, false, iter::empty())),
|
|
|
- [EXPECTED_OUT_STATE].map(State::new_empty_owned).into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
+ Some(Message::new(EXPECTED_IN_MSG, false, [])),
|
|
|
+ [EXPECTED_OUT_STATE].map(State::new_empty_owned),
|
|
|
+ [],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -764,10 +818,10 @@ let states = [{}];
|
|
|
const EXPECTED_OUT_STATE: &str = "End";
|
|
|
let input = format!("{EXPECTED_IN_STATE}?{EXPECTED_IN_MSG}::Reply -> {EXPECTED_OUT_STATE}");
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
- Some(Message::new(EXPECTED_IN_MSG, true, iter::empty())),
|
|
|
- [EXPECTED_OUT_STATE].map(State::new_empty_owned).into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
+ Some(Message::new(EXPECTED_IN_MSG, true, [])),
|
|
|
+ [EXPECTED_OUT_STATE].map(State::new_empty_owned),
|
|
|
+ [],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -786,14 +840,10 @@ let states = [{}];
|
|
|
EXPECTED_OWNED_STATES[0], EXPECTED_OWNED_STATES[1]
|
|
|
);
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
- Some(Message::new(
|
|
|
- EXPECTED_IN_MSG,
|
|
|
- true,
|
|
|
- EXPECTED_OWNED_STATES.into_iter(),
|
|
|
- )),
|
|
|
- [EXPECTED_OUT_STATE].map(State::new_empty_owned).into_iter(),
|
|
|
- iter::empty(),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
+ Some(Message::new(EXPECTED_IN_MSG, true, EXPECTED_OWNED_STATES)),
|
|
|
+ [EXPECTED_OUT_STATE].map(State::new_empty_owned),
|
|
|
+ [],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -809,14 +859,13 @@ let states = [{}];
|
|
|
const EXPECTED_DEST_MSG: &str = "DeathNote";
|
|
|
let input = format!("{EXPECTED_IN_STATE} -> {EXPECTED_OUT_STATE} >{EXPECTED_DEST_STATE}!{EXPECTED_DEST_MSG}");
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
None,
|
|
|
- [EXPECTED_OUT_STATE].map(State::new_empty_owned).into_iter(),
|
|
|
+ [EXPECTED_OUT_STATE].map(State::new_empty_owned),
|
|
|
[Dest::new(
|
|
|
- DestinationState::Individual(State::new(EXPECTED_DEST_STATE, iter::empty())),
|
|
|
- Message::new(EXPECTED_DEST_MSG, false, iter::empty()),
|
|
|
- )]
|
|
|
- .into_iter(),
|
|
|
+ DestinationState::Individual(State::new(EXPECTED_DEST_STATE, [])),
|
|
|
+ Message::new(EXPECTED_DEST_MSG, false, []),
|
|
|
+ )],
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -834,17 +883,15 @@ let states = [{}];
|
|
|
let dest_list = EXPECTED_DESTS.map(|(l, r)| format!("{l}!{r}")).join(", ");
|
|
|
let input = format!("{EXPECTED_IN_STATE}?{EXPECTED_IN_MSG} -> {states_list} >{dest_list}");
|
|
|
let expected = Transition::new(
|
|
|
- State::new(EXPECTED_IN_STATE, iter::empty()),
|
|
|
- Some(Message::new(EXPECTED_IN_MSG, false, iter::empty())),
|
|
|
- EXPECTED_OUT_STATES.map(State::new_empty_owned).into_iter(),
|
|
|
- EXPECTED_DESTS
|
|
|
- .map(|(l, r)| {
|
|
|
- Dest::new(
|
|
|
- DestinationState::Individual(State::new(l, iter::empty())),
|
|
|
- Message::new(r, false, iter::empty()),
|
|
|
- )
|
|
|
- })
|
|
|
- .into_iter(),
|
|
|
+ State::new(EXPECTED_IN_STATE, []),
|
|
|
+ Some(Message::new(EXPECTED_IN_MSG, false, [])),
|
|
|
+ EXPECTED_OUT_STATES.map(State::new_empty_owned),
|
|
|
+ EXPECTED_DESTS.map(|(l, r)| {
|
|
|
+ Dest::new(
|
|
|
+ DestinationState::Individual(State::new(l, [])),
|
|
|
+ Message::new(r, false, []),
|
|
|
+ )
|
|
|
+ }),
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Transition>(&input).unwrap();
|
|
@@ -852,23 +899,10 @@ let states = [{}];
|
|
|
assert_eq!(expected, actual);
|
|
|
}
|
|
|
|
|
|
- impl State {
|
|
|
- fn new(state_trait: &str, owned_states: impl Iterator<Item = &'static str>) -> Self {
|
|
|
- Self {
|
|
|
- state_trait: ident(state_trait),
|
|
|
- owned_states: IdentArray::new(owned_states),
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn new_empty_owned(state_trait: &str) -> Self {
|
|
|
- Self::new(state_trait, iter::empty())
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn state_parse_no_owned_states() {
|
|
|
const EXPECTED_TRAIT: &str = "Contained";
|
|
|
- let expected = State::new(EXPECTED_TRAIT, iter::empty());
|
|
|
+ let expected = State::new(EXPECTED_TRAIT, []);
|
|
|
|
|
|
let actual = parse_str::<State>(EXPECTED_TRAIT).unwrap();
|
|
|
|
|
@@ -883,27 +917,21 @@ let states = [{}];
|
|
|
"{EXPECTED_TRAIT}[{}, {}]",
|
|
|
EXPECTED_OWNED[0], EXPECTED_OWNED[1]
|
|
|
);
|
|
|
- let expected = State::new(EXPECTED_TRAIT, EXPECTED_OWNED.into_iter());
|
|
|
+ let expected = State::new(EXPECTED_TRAIT, EXPECTED_OWNED);
|
|
|
|
|
|
let actual = parse_str::<State>(&input).unwrap();
|
|
|
|
|
|
assert_eq!(expected, actual);
|
|
|
}
|
|
|
|
|
|
- impl Dest {
|
|
|
- fn new(state: DestinationState, msg: Message) -> Self {
|
|
|
- Self { state, msg }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn dest_parse() {
|
|
|
const EXPECTED_STATE: &str = "Opened";
|
|
|
const EXPECTED_MSG: &str = "Read";
|
|
|
let input = format!("{EXPECTED_STATE}!{EXPECTED_MSG}");
|
|
|
let expected = Dest::new(
|
|
|
- DestinationState::Individual(State::new(EXPECTED_STATE, iter::empty())),
|
|
|
- Message::new(EXPECTED_MSG, false, iter::empty()),
|
|
|
+ DestinationState::Individual(State::new(EXPECTED_STATE, [])),
|
|
|
+ Message::new(EXPECTED_MSG, false, []),
|
|
|
);
|
|
|
|
|
|
let actual = parse_str::<Dest>(&input).unwrap();
|
|
@@ -914,7 +942,7 @@ let states = [{}];
|
|
|
#[test]
|
|
|
fn destination_state_parse_regular() {
|
|
|
const EXPECTED_DEST_STATE: &str = "Listening";
|
|
|
- let expected = DestinationState::Individual(State::new(EXPECTED_DEST_STATE, iter::empty()));
|
|
|
+ let expected = DestinationState::Individual(State::new(EXPECTED_DEST_STATE, []));
|
|
|
|
|
|
let actual = parse_str::<DestinationState>(EXPECTED_DEST_STATE).unwrap();
|
|
|
|
|
@@ -929,10 +957,8 @@ let states = [{}];
|
|
|
"{EXPECTED_DEST_STATE}[{}]",
|
|
|
EXPECTED_OWNED_STATES.join(", ")
|
|
|
);
|
|
|
- let expected = DestinationState::Individual(State::new(
|
|
|
- EXPECTED_DEST_STATE,
|
|
|
- EXPECTED_OWNED_STATES.into_iter(),
|
|
|
- ));
|
|
|
+ let expected =
|
|
|
+ DestinationState::Individual(State::new(EXPECTED_DEST_STATE, EXPECTED_OWNED_STATES));
|
|
|
|
|
|
let actual = parse_str::<DestinationState>(&input).unwrap();
|
|
|
|
|
@@ -942,7 +968,7 @@ let states = [{}];
|
|
|
#[test]
|
|
|
fn destination_state_parse_service() {
|
|
|
const EXPECTED_DEST_STATE: &str = "Listening";
|
|
|
- let expected = DestinationState::Service(State::new(EXPECTED_DEST_STATE, iter::empty()));
|
|
|
+ let expected = DestinationState::Service(State::new(EXPECTED_DEST_STATE, []));
|
|
|
let input = format!("service({EXPECTED_DEST_STATE})");
|
|
|
|
|
|
let actual = parse_str::<DestinationState>(&input).unwrap();
|
|
@@ -968,42 +994,13 @@ let states = [{}];
|
|
|
assert_eq!(DestinationState::MULTI_STATE_ERR, err_str);
|
|
|
}
|
|
|
|
|
|
- impl Message {
|
|
|
- fn new(
|
|
|
- msg_type: &str,
|
|
|
- is_reply: bool,
|
|
|
- owned_states: impl Iterator<Item = &'static str>,
|
|
|
- ) -> Self {
|
|
|
- let (reply_part, ident_field) = if is_reply {
|
|
|
- let reply_part = MessageReplyPart {
|
|
|
- colons: Token),
|
|
|
- reply: ident(MessageReplyPart::REPLY_IDENT),
|
|
|
- };
|
|
|
- let variant = format_ident!("{}{}", msg_type, MessageReplyPart::REPLY_IDENT);
|
|
|
- (Some(reply_part), Some(variant))
|
|
|
- } else {
|
|
|
- (None, None)
|
|
|
- };
|
|
|
- Self {
|
|
|
- msg_type: ident(msg_type),
|
|
|
- reply_part,
|
|
|
- owned_states: IdentArray::new(owned_states),
|
|
|
- ident: ident_field,
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
#[test]
|
|
|
fn message_new() {
|
|
|
const EXPECTED_MSG_TYPE: &str = "Orders";
|
|
|
const EXPECTED_IS_REPLY: bool = true;
|
|
|
const EXPECTED_OWNED_STATES: [&str; 2] = ["First", "Second"];
|
|
|
|
|
|
- let actual = Message::new(
|
|
|
- EXPECTED_MSG_TYPE,
|
|
|
- EXPECTED_IS_REPLY,
|
|
|
- EXPECTED_OWNED_STATES.into_iter(),
|
|
|
- );
|
|
|
+ let actual = Message::new(EXPECTED_MSG_TYPE, EXPECTED_IS_REPLY, EXPECTED_OWNED_STATES);
|
|
|
|
|
|
assert_eq!(actual.msg_type, EXPECTED_MSG_TYPE);
|
|
|
assert_eq!(actual.is_reply(), EXPECTED_IS_REPLY);
|
|
@@ -1015,7 +1012,7 @@ let states = [{}];
|
|
|
#[test]
|
|
|
fn message_parse_regular() {
|
|
|
const EXPECTED_MSG: &str = "Write";
|
|
|
- let expected = Message::new(EXPECTED_MSG, false, iter::empty());
|
|
|
+ let expected = Message::new(EXPECTED_MSG, false, []);
|
|
|
|
|
|
let actual = parse_str::<Message>(EXPECTED_MSG).unwrap();
|
|
|
|
|
@@ -1026,7 +1023,7 @@ let states = [{}];
|
|
|
fn message_parse_reply() {
|
|
|
const EXPECTED_MSG: &str = "ReadAttr";
|
|
|
let input = format!("{EXPECTED_MSG}::Reply");
|
|
|
- let expected = Message::new(EXPECTED_MSG, true, iter::empty());
|
|
|
+ let expected = Message::new(EXPECTED_MSG, true, []);
|
|
|
|
|
|
let actual = parse_str::<Message>(&input).unwrap();
|
|
|
|
|
@@ -1051,7 +1048,7 @@ let states = [{}];
|
|
|
const EXPECTED_MSG: &str = "Open";
|
|
|
const OWNED_STATES: [&str; 2] = ["Handle0", "Handle1"];
|
|
|
let input = format!("{EXPECTED_MSG}[{}, {}]", OWNED_STATES[0], OWNED_STATES[1]);
|
|
|
- let expected = Message::new(EXPECTED_MSG, false, OWNED_STATES.into_iter());
|
|
|
+ let expected = Message::new(EXPECTED_MSG, false, OWNED_STATES);
|
|
|
|
|
|
let actual = parse_str::<Message>(&input).unwrap();
|
|
|
|
|
@@ -1066,7 +1063,7 @@ let states = [{}];
|
|
|
"{EXPECTED_MSG}::Reply[{}, {}]",
|
|
|
OWNED_STATES[0], OWNED_STATES[1]
|
|
|
);
|
|
|
- let expected = Message::new(EXPECTED_MSG, true, OWNED_STATES.into_iter());
|
|
|
+ let expected = Message::new(EXPECTED_MSG, true, OWNED_STATES);
|
|
|
|
|
|
let actual = parse_str::<Message>(&input).unwrap();
|
|
|
|