1use crate::{
2 buffers::{self, Buffer, Buffers, CapacityError, DefaultBuffers},
3 Comment, GCode, Span, Word,
4};
5use core::fmt::{self, Debug, Formatter};
6
7#[derive(Clone, PartialEq)]
9#[cfg_attr(
10 feature = "serde-1",
11 derive(serde_derive::Serialize, serde_derive::Deserialize)
12)]
13pub struct Line<'input, B: Buffers<'input> = DefaultBuffers> {
14 gcodes: B::Commands,
15 comments: B::Comments,
16 line_number: Option<Word>,
17 span: Span,
18}
19
20impl<'input, B> Debug for Line<'input, B>
21where
22 B: Buffers<'input>,
23{
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 let Line {
27 gcodes,
28 comments,
29 line_number,
30 span,
31 } = self;
32
33 f.debug_struct("Line")
34 .field("gcodes", &buffers::debug(gcodes))
35 .field("comments", &buffers::debug(comments))
36 .field("line_number", line_number)
37 .field("span", span)
38 .finish()
39 }
40}
41
42impl<'input, B> Default for Line<'input, B>
43where
44 B: Buffers<'input>,
45 B::Commands: Default,
46 B::Comments: Default,
47{
48 fn default() -> Line<'input, B> {
49 Line {
50 gcodes: B::Commands::default(),
51 comments: B::Comments::default(),
52 line_number: None,
53 span: Span::default(),
54 }
55 }
56}
57
58impl<'input, B: Buffers<'input>> Line<'input, B> {
59 pub fn gcodes(&self) -> &[GCode<B::Arguments>] { self.gcodes.as_slice() }
61
62 pub fn comments(&self) -> &[Comment<'input>] { self.comments.as_slice() }
64
65 pub fn push_gcode(
67 &mut self,
68 gcode: GCode<B::Arguments>,
69 ) -> Result<(), CapacityError<GCode<B::Arguments>>> {
70 let span = self.span.merge(gcode.span());
72 self.gcodes.try_push(gcode)?;
73 self.span = span;
74
75 Ok(())
76 }
77
78 pub fn push_comment(
80 &mut self,
81 comment: Comment<'input>,
82 ) -> Result<(), CapacityError<Comment<'input>>> {
83 let span = self.span.merge(comment.span);
84 self.comments.try_push(comment)?;
85 self.span = span;
86 Ok(())
87 }
88
89 pub fn is_empty(&self) -> bool {
91 self.gcodes.as_slice().is_empty()
92 && self.comments.as_slice().is_empty()
93 && self.line_number().is_none()
94 }
95
96 pub fn line_number(&self) -> Option<Word> { self.line_number }
98
99 pub fn set_line_number<W: Into<Option<Word>>>(&mut self, line_number: W) {
101 match line_number.into() {
102 Some(n) => {
103 self.span = self.span.merge(n.span);
104 self.line_number = Some(n);
105 },
106 None => self.line_number = None,
107 }
108 }
109
110 pub fn span(&self) -> Span { self.span }
112
113 pub(crate) fn into_gcodes(self) -> B::Commands { self.gcodes }
114}