1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Module dedicated to [Connection] parsing.
use core::slice::Windows;
use super::word::{Kind, Word};
use super::{CommentsAnnotations, PositionnedString};
use crate::ScriptError;
/// Structure describing a textual connection.
///
/// It owns starting point and ending point names, and the names of data associated with, if any.
#[derive(Clone, Debug)]
pub struct Connection {
pub annotations: Option<CommentsAnnotations>,
pub name_start_point: PositionnedString,
pub name_data_out: Option<PositionnedString>,
pub name_end_point: PositionnedString,
pub name_data_in: Option<PositionnedString>,
}
impl Connection {
/// Build a connection by parsing words, starting when the end point name is expected.
///
/// * `name`: The name already parsed for the start point (its accuracy is under responsibility of the caller).
/// * `iter`: Iterator over words list, next() being expected to be the end point name.
///
pub fn build_from_name_end_point(
annotations: Option<CommentsAnnotations>,
name: PositionnedString,
iter: &mut Windows<Word>,
) -> Result<Self, ScriptError> {
let name_end_point = iter
.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(77))
.and_then(|w| {
if w.kind != Some(Kind::Name) {
Err(ScriptError::word(78, w.clone(), &[Kind::Name]))
} else {
Ok(w.into())
}
})?;
Ok(Self {
annotations,
name_start_point: name,
name_data_out: None,
name_end_point,
name_data_in: None,
})
}
/// Build a connection by parsing words, starting when then name of data out is expected.
///
/// * `name`: The name already parsed for the data out (its accuracy is under responsibility of the caller).
/// * `iter`: Iterator over words list, next() being expected to be the data out name.
///
pub fn build_from_name_data_out(
annotations: Option<CommentsAnnotations>,
name: PositionnedString,
iter: &mut Windows<Word>,
) -> Result<Self, ScriptError> {
let name_data_out = iter
.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(79))
.and_then(|w| {
if w.kind != Some(Kind::Name) {
Err(ScriptError::word(80, w.clone(), &[Kind::Name]))
} else {
Ok(w.into())
}
})?;
iter.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(85))
.and_then(|w| {
if w.kind != Some(Kind::RightArrow) {
Err(ScriptError::word(86, w.clone(), &[Kind::RightArrow]))
} else {
Ok(())
}
})?;
let name_end_point = iter
.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(81))
.and_then(|w| {
if w.kind != Some(Kind::Name) {
Err(ScriptError::word(82, w.clone(), &[Kind::Name]))
} else {
Ok(w.into())
}
})?;
iter.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(87))
.and_then(|w| {
if w.kind != Some(Kind::Dot) {
Err(ScriptError::word(88, w.clone(), &[Kind::Dot]))
} else {
Ok(())
}
})?;
let name_data_in = iter
.next()
.map(|s| &s[0])
.ok_or_else(|| ScriptError::end_of_script(83))
.and_then(|w| {
if w.kind != Some(Kind::Name) {
Err(ScriptError::word(84, w.clone(), &[Kind::Name]))
} else {
Ok(w.into())
}
})?;
Ok(Self {
annotations,
name_start_point: name,
name_data_out: Some(name_data_out),
name_end_point: name_end_point,
name_data_in: Some(name_data_in),
})
}
}