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
use crate::{
buffers::{self, Buffer, Buffers, CapacityError, DefaultBuffers},
Comment, GCode, Span, Word,
};
use core::fmt::{self, Debug, Formatter};
#[derive(Clone, PartialEq)]
#[cfg_attr(
feature = "serde-1",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Line<'input, B: Buffers<'input> = DefaultBuffers> {
gcodes: B::Commands,
comments: B::Comments,
line_number: Option<Word>,
span: Span,
}
impl<'input, B> Debug for Line<'input, B>
where
B: Buffers<'input>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let Line {
gcodes,
comments,
line_number,
span,
} = self;
f.debug_struct("Line")
.field("gcodes", &buffers::debug(gcodes))
.field("comments", &buffers::debug(comments))
.field("line_number", line_number)
.field("span", span)
.finish()
}
}
impl<'input, B> Default for Line<'input, B>
where
B: Buffers<'input>,
B::Commands: Default,
B::Comments: Default,
{
fn default() -> Line<'input, B> {
Line {
gcodes: B::Commands::default(),
comments: B::Comments::default(),
line_number: None,
span: Span::default(),
}
}
}
impl<'input, B: Buffers<'input>> Line<'input, B> {
pub fn gcodes(&self) -> &[GCode<B::Arguments>] { self.gcodes.as_slice() }
pub fn comments(&self) -> &[Comment<'input>] { self.comments.as_slice() }
pub fn push_gcode(
&mut self,
gcode: GCode<B::Arguments>,
) -> Result<(), CapacityError<GCode<B::Arguments>>> {
let span = self.span.merge(gcode.span());
self.gcodes.try_push(gcode)?;
self.span = span;
Ok(())
}
pub fn push_comment(
&mut self,
comment: Comment<'input>,
) -> Result<(), CapacityError<Comment<'input>>> {
let span = self.span.merge(comment.span);
self.comments.try_push(comment)?;
self.span = span;
Ok(())
}
pub fn is_empty(&self) -> bool {
self.gcodes.as_slice().is_empty()
&& self.comments.as_slice().is_empty()
&& self.line_number().is_none()
}
pub fn line_number(&self) -> Option<Word> { self.line_number }
pub fn set_line_number<W: Into<Option<Word>>>(&mut self, line_number: W) {
match line_number.into() {
Some(n) => {
self.span = self.span.merge(n.span);
self.line_number = Some(n);
},
None => self.line_number = None,
}
}
pub fn span(&self) -> Span { self.span }
pub(crate) fn into_gcodes(self) -> B::Commands { self.gcodes }
}