1#![cfg_attr(rustfmt, rustfmt::skip)]
3
4use super::{MicalLanguage, SyntaxKind, SyntaxNode, SyntaxToken};
5use core::fmt;
6pub use rowan::ast::{AstChildren, AstNode};
7
8mod support {
9 use super::*;
10 pub use rowan::ast::support::*;
11 pub struct DebugSyntaxToken(pub Option<SyntaxToken>);
12 impl fmt::Debug for DebugSyntaxToken {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 match &self.0 {
15 Some(token) => fmt::Debug::fmt(token, f),
16 None => f.write_str("none"),
17 }
18 }
19 }
20 pub struct DebugAstChildren<N: AstNode>(pub AstChildren<N>);
21 impl<N: AstNode + fmt::Debug + Clone> fmt::Debug for DebugAstChildren<N> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_list().entries(self.0.clone().map(|ast| DebugAstNode(Some(ast)))).finish()
24 }
25 }
26 pub struct DebugAstNode<N: AstNode>(pub Option<N>);
27 impl<N: AstNode + fmt::Debug + Clone> fmt::Debug for DebugAstNode<N> {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match &self.0 {
30 Some(node) => fmt::Debug::fmt(node, f),
31 None => f.write_str("none"),
32 }
33 }
34 }
35}
36
37#[derive(Clone)]
38pub struct SourceFile(SyntaxNode);
39impl AstNode for SourceFile {
40 type Language = MicalLanguage;
41 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
42 kind == SyntaxKind::SOURCE_FILE
43 }
44 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
45 if Self::can_cast(node.kind()) {
46 Some(Self(node))
47 } else {
48 None
49 }
50 }
51 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
52 &self.0
53 }
54}
55impl SourceFile {
56 pub fn shebang(&self) -> Option<SyntaxToken> {
57 support::token(AstNode::syntax(self), SyntaxKind::SHEBANG)
58 }
59 pub fn items(&self) -> AstChildren<Item> {
60 support::children(AstNode::syntax(self))
61 }
62}
63impl fmt::Display for SourceFile {
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 fmt::Display::fmt(self.syntax(), f)
66 }
67}
68impl fmt::Debug for SourceFile {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 f.debug_struct("SourceFile")
71 .field("shebang", &support::DebugSyntaxToken(self.shebang()))
72 .field("items", &support::DebugAstChildren(self.items()))
73 .finish()
74 }
75}
76
77#[derive(Clone)]
78pub enum Item {
79 Entry(Entry),
80 PrefixBlock(PrefixBlock),
81 Directive(Directive),
82}
83impl AstNode for Item {
84 type Language = MicalLanguage;
85 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
86 <Entry as AstNode>::can_cast(kind)
87 || <PrefixBlock as AstNode>::can_cast(kind)
88 || <Directive as AstNode>::can_cast(kind)
89 }
90 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
91 let kind = node.kind();
92 if <Entry as AstNode>::can_cast(kind) {
93 let casted = <Entry as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
94 return Some(Self::Entry(casted));
95 }
96 if <PrefixBlock as AstNode>::can_cast(kind) {
97 let casted = <PrefixBlock as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
98 return Some(Self::PrefixBlock(casted));
99 }
100 if <Directive as AstNode>::can_cast(kind) {
101 let casted = <Directive as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
102 return Some(Self::Directive(casted));
103 }
104 None
105 }
106 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
107 match self {
108 Self::Entry(x) => x.syntax(),
109 Self::PrefixBlock(x) => x.syntax(),
110 Self::Directive(x) => x.syntax(),
111 }
112 }
113}
114impl fmt::Display for Item {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 fmt::Display::fmt(self.syntax(), f)
117 }
118}
119impl fmt::Debug for Item {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 match self {
122 Self::Entry(x) => fmt::Debug::fmt(x, f),
123 Self::PrefixBlock(x) => fmt::Debug::fmt(x, f),
124 Self::Directive(x) => fmt::Debug::fmt(x, f),
125 }
126 }
127}
128
129#[derive(Clone)]
130pub struct Entry(SyntaxNode);
131impl AstNode for Entry {
132 type Language = MicalLanguage;
133 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
134 kind == SyntaxKind::ENTRY
135 }
136 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
137 if Self::can_cast(node.kind()) {
138 Some(Self(node))
139 } else {
140 None
141 }
142 }
143 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
144 &self.0
145 }
146}
147impl Entry {
148 pub fn key(&self) -> Option<Key> {
149 support::child(AstNode::syntax(self))
150 }
151 pub fn value(&self) -> Option<Value> {
152 support::child(AstNode::syntax(self))
153 }
154}
155impl fmt::Display for Entry {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 fmt::Display::fmt(self.syntax(), f)
158 }
159}
160impl fmt::Debug for Entry {
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 f.debug_struct("Entry")
163 .field("key", &support::DebugAstNode(self.key()))
164 .field("value", &support::DebugAstNode(self.value()))
165 .finish()
166 }
167}
168
169#[derive(Clone)]
170pub struct PrefixBlock(SyntaxNode);
171impl AstNode for PrefixBlock {
172 type Language = MicalLanguage;
173 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
174 kind == SyntaxKind::PREFIX_BLOCK
175 }
176 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
177 if Self::can_cast(node.kind()) {
178 Some(Self(node))
179 } else {
180 None
181 }
182 }
183 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
184 &self.0
185 }
186}
187impl PrefixBlock {
188 pub fn key(&self) -> Option<Key> {
189 support::child(AstNode::syntax(self))
190 }
191 pub fn open_brace(&self) -> Option<SyntaxToken> {
192 support::token(AstNode::syntax(self), SyntaxKind::OPEN_BRACE)
193 }
194 pub fn items(&self) -> AstChildren<Item> {
195 support::children(AstNode::syntax(self))
196 }
197 pub fn close_brace(&self) -> Option<SyntaxToken> {
198 support::token(AstNode::syntax(self), SyntaxKind::CLOSE_BRACE)
199 }
200}
201impl fmt::Display for PrefixBlock {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 fmt::Display::fmt(self.syntax(), f)
204 }
205}
206impl fmt::Debug for PrefixBlock {
207 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
208 f.debug_struct("PrefixBlock")
209 .field("key", &support::DebugAstNode(self.key()))
210 .field("open_brace", &support::DebugSyntaxToken(self.open_brace()))
211 .field("items", &support::DebugAstChildren(self.items()))
212 .field("close_brace", &support::DebugSyntaxToken(self.close_brace()))
213 .finish()
214 }
215}
216
217#[derive(Clone)]
218pub struct Directive(SyntaxNode);
219impl AstNode for Directive {
220 type Language = MicalLanguage;
221 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
222 kind == SyntaxKind::DIRECTIVE
223 }
224 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
225 if Self::can_cast(node.kind()) {
226 Some(Self(node))
227 } else {
228 None
229 }
230 }
231 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
232 &self.0
233 }
234}
235impl Directive {
236 pub fn sharp(&self) -> Option<SyntaxToken> {
237 support::token(AstNode::syntax(self), SyntaxKind::SHARP)
238 }
239 pub fn name(&self) -> Option<SyntaxToken> {
240 support::token(AstNode::syntax(self), SyntaxKind::WORD)
241 }
242 pub fn args(&self) -> Option<LineString> {
243 support::child(AstNode::syntax(self))
244 }
245}
246impl fmt::Display for Directive {
247 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248 fmt::Display::fmt(self.syntax(), f)
249 }
250}
251impl fmt::Debug for Directive {
252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
253 f.debug_struct("Directive")
254 .field("sharp", &support::DebugSyntaxToken(self.sharp()))
255 .field("name", &support::DebugSyntaxToken(self.name()))
256 .field("args", &support::DebugAstNode(self.args()))
257 .finish()
258 }
259}
260
261#[derive(Clone)]
262pub enum Key {
263 Word(WordKey),
264 Quoted(QuotedKey),
265}
266impl AstNode for Key {
267 type Language = MicalLanguage;
268 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
269 <WordKey as AstNode>::can_cast(kind) || <QuotedKey as AstNode>::can_cast(kind)
270 }
271 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
272 let kind = node.kind();
273 if <WordKey as AstNode>::can_cast(kind) {
274 let casted = <WordKey as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
275 return Some(Self::Word(casted));
276 }
277 if <QuotedKey as AstNode>::can_cast(kind) {
278 let casted = <QuotedKey as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
279 return Some(Self::Quoted(casted));
280 }
281 None
282 }
283 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
284 match self {
285 Self::Word(x) => x.syntax(),
286 Self::Quoted(x) => x.syntax(),
287 }
288 }
289}
290impl fmt::Display for Key {
291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
292 fmt::Display::fmt(self.syntax(), f)
293 }
294}
295impl fmt::Debug for Key {
296 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297 match self {
298 Self::Word(x) => fmt::Debug::fmt(x, f),
299 Self::Quoted(x) => fmt::Debug::fmt(x, f),
300 }
301 }
302}
303
304#[derive(Clone)]
305pub enum Value {
306 Integer(Integer),
307 Boolean(Boolean),
308 QuotedString(QuotedString),
309 LineString(LineString),
310 BlockString(BlockString),
311}
312impl AstNode for Value {
313 type Language = MicalLanguage;
314 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
315 <Integer as AstNode>::can_cast(kind)
316 || <Boolean as AstNode>::can_cast(kind)
317 || <QuotedString as AstNode>::can_cast(kind)
318 || <LineString as AstNode>::can_cast(kind)
319 || <BlockString as AstNode>::can_cast(kind)
320 }
321 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
322 let kind = node.kind();
323 if <Integer as AstNode>::can_cast(kind) {
324 let casted = <Integer as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
325 return Some(Self::Integer(casted));
326 }
327 if <Boolean as AstNode>::can_cast(kind) {
328 let casted = <Boolean as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
329 return Some(Self::Boolean(casted));
330 }
331 if <QuotedString as AstNode>::can_cast(kind) {
332 let casted = <QuotedString as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
333 return Some(Self::QuotedString(casted));
334 }
335 if <LineString as AstNode>::can_cast(kind) {
336 let casted = <LineString as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
337 return Some(Self::LineString(casted));
338 }
339 if <BlockString as AstNode>::can_cast(kind) {
340 let casted = <BlockString as AstNode>::cast(node).expect("Invalid `can_cast` implementation");
341 return Some(Self::BlockString(casted));
342 }
343 None
344 }
345 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
346 match self {
347 Self::Integer(x) => x.syntax(),
348 Self::Boolean(x) => x.syntax(),
349 Self::QuotedString(x) => x.syntax(),
350 Self::LineString(x) => x.syntax(),
351 Self::BlockString(x) => x.syntax(),
352 }
353 }
354}
355impl fmt::Display for Value {
356 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
357 fmt::Display::fmt(self.syntax(), f)
358 }
359}
360impl fmt::Debug for Value {
361 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
362 match self {
363 Self::Integer(x) => fmt::Debug::fmt(x, f),
364 Self::Boolean(x) => fmt::Debug::fmt(x, f),
365 Self::QuotedString(x) => fmt::Debug::fmt(x, f),
366 Self::LineString(x) => fmt::Debug::fmt(x, f),
367 Self::BlockString(x) => fmt::Debug::fmt(x, f),
368 }
369 }
370}
371
372#[derive(Clone)]
373pub struct LineString(SyntaxNode);
374impl AstNode for LineString {
375 type Language = MicalLanguage;
376 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
377 kind == SyntaxKind::LINE_STRING
378 }
379 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
380 if Self::can_cast(node.kind()) {
381 Some(Self(node))
382 } else {
383 None
384 }
385 }
386 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
387 &self.0
388 }
389}
390impl LineString {
391 pub fn string(&self) -> Option<SyntaxToken> {
392 support::token(AstNode::syntax(self), SyntaxKind::STRING)
393 }
394}
395impl fmt::Display for LineString {
396 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
397 fmt::Display::fmt(self.syntax(), f)
398 }
399}
400impl fmt::Debug for LineString {
401 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
402 f.debug_struct("LineString").field("string", &support::DebugSyntaxToken(self.string())).finish()
403 }
404}
405
406#[derive(Clone)]
407pub struct WordKey(SyntaxNode);
408impl AstNode for WordKey {
409 type Language = MicalLanguage;
410 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
411 kind == SyntaxKind::WORD_KEY
412 }
413 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
414 if Self::can_cast(node.kind()) {
415 Some(Self(node))
416 } else {
417 None
418 }
419 }
420 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
421 &self.0
422 }
423}
424impl WordKey {
425 pub fn word(&self) -> Option<SyntaxToken> {
426 support::token(AstNode::syntax(self), SyntaxKind::WORD)
427 }
428}
429impl fmt::Display for WordKey {
430 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431 fmt::Display::fmt(self.syntax(), f)
432 }
433}
434impl fmt::Debug for WordKey {
435 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
436 f.debug_struct("WordKey").field("word", &support::DebugSyntaxToken(self.word())).finish()
437 }
438}
439
440#[derive(Clone)]
441pub struct QuotedKey(SyntaxNode);
442impl AstNode for QuotedKey {
443 type Language = MicalLanguage;
444 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
445 kind == SyntaxKind::QUOTED_KEY
446 }
447 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
448 if Self::can_cast(node.kind()) {
449 Some(Self(node))
450 } else {
451 None
452 }
453 }
454 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
455 &self.0
456 }
457}
458impl QuotedKey {
459 pub fn open_quote(&self) -> Option<SyntaxToken> {
460 self.syntax()
461 .children_with_tokens()
462 .filter_map(|it| it.into_token())
463 .find(|it| matches!(it.kind(), SyntaxKind::DOUBLE_QUOTE | SyntaxKind::SINGLE_QUOTE))
464 }
465 pub fn string(&self) -> Option<SyntaxToken> {
466 support::token(AstNode::syntax(self), SyntaxKind::STRING)
467 }
468 pub fn close_quote(&self) -> Option<SyntaxToken> {
469 self.syntax()
470 .children_with_tokens()
471 .filter_map(|it| it.into_token())
472 .find(|it| matches!(it.kind(), SyntaxKind::DOUBLE_QUOTE | SyntaxKind::SINGLE_QUOTE))
473 }
474}
475impl fmt::Display for QuotedKey {
476 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
477 fmt::Display::fmt(self.syntax(), f)
478 }
479}
480impl fmt::Debug for QuotedKey {
481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482 f.debug_struct("QuotedKey")
483 .field("open_quote", &support::DebugSyntaxToken(self.open_quote()))
484 .field("string", &support::DebugSyntaxToken(self.string()))
485 .field("close_quote", &support::DebugSyntaxToken(self.close_quote()))
486 .finish()
487 }
488}
489
490#[derive(Clone)]
491pub struct Integer(SyntaxNode);
492impl AstNode for Integer {
493 type Language = MicalLanguage;
494 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
495 kind == SyntaxKind::INTEGER
496 }
497 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
498 if Self::can_cast(node.kind()) {
499 Some(Self(node))
500 } else {
501 None
502 }
503 }
504 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
505 &self.0
506 }
507}
508impl Integer {
509 pub fn sign(&self) -> Option<SyntaxToken> {
510 self.syntax()
511 .children_with_tokens()
512 .filter_map(|it| it.into_token())
513 .find(|it| matches!(it.kind(), SyntaxKind::PLUS | SyntaxKind::MINUS))
514 }
515 pub fn numeral(&self) -> Option<SyntaxToken> {
516 support::token(AstNode::syntax(self), SyntaxKind::NUMERAL)
517 }
518}
519impl fmt::Display for Integer {
520 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
521 fmt::Display::fmt(self.syntax(), f)
522 }
523}
524impl fmt::Debug for Integer {
525 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
526 f.debug_struct("Integer")
527 .field("sign", &support::DebugSyntaxToken(self.sign()))
528 .field("numeral", &support::DebugSyntaxToken(self.numeral()))
529 .finish()
530 }
531}
532
533#[derive(Clone)]
534pub struct Boolean(SyntaxNode);
535impl AstNode for Boolean {
536 type Language = MicalLanguage;
537 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
538 kind == SyntaxKind::BOOLEAN
539 }
540 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
541 if Self::can_cast(node.kind()) {
542 Some(Self(node))
543 } else {
544 None
545 }
546 }
547 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
548 &self.0
549 }
550}
551impl Boolean {
552 pub fn token(&self) -> Option<SyntaxToken> {
553 self.syntax()
554 .children_with_tokens()
555 .filter_map(|it| it.into_token())
556 .find(|it| matches!(it.kind(), SyntaxKind::TRUE | SyntaxKind::FALSE))
557 }
558 pub fn kind(&self) -> Option<BooleanKind> {
559 let token = self.token()?;
560 let kind = match token.kind() {
561 SyntaxKind::TRUE => BooleanKind::True,
562 SyntaxKind::FALSE => BooleanKind::False,
563 _ => return None,
564 };
565 Some(kind)
566 }
567}
568pub enum BooleanKind {
569 True,
570 False,
571}
572impl fmt::Display for Boolean {
573 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
574 fmt::Display::fmt(self.syntax(), f)
575 }
576}
577impl fmt::Debug for Boolean {
578 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579 f.debug_struct("Boolean").field("token", &support::DebugSyntaxToken(self.token())).finish()
580 }
581}
582
583#[derive(Clone)]
584pub struct QuotedString(SyntaxNode);
585impl AstNode for QuotedString {
586 type Language = MicalLanguage;
587 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
588 kind == SyntaxKind::QUOTED_STRING
589 }
590 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
591 if Self::can_cast(node.kind()) {
592 Some(Self(node))
593 } else {
594 None
595 }
596 }
597 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
598 &self.0
599 }
600}
601impl QuotedString {
602 pub fn open_quote(&self) -> Option<SyntaxToken> {
603 self.syntax()
604 .children_with_tokens()
605 .filter_map(|it| it.into_token())
606 .find(|it| matches!(it.kind(), SyntaxKind::DOUBLE_QUOTE | SyntaxKind::SINGLE_QUOTE))
607 }
608 pub fn string(&self) -> Option<SyntaxToken> {
609 support::token(AstNode::syntax(self), SyntaxKind::STRING)
610 }
611 pub fn close_quote(&self) -> Option<SyntaxToken> {
612 self.syntax()
613 .children_with_tokens()
614 .filter_map(|it| it.into_token())
615 .find(|it| matches!(it.kind(), SyntaxKind::DOUBLE_QUOTE | SyntaxKind::SINGLE_QUOTE))
616 }
617}
618impl fmt::Display for QuotedString {
619 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
620 fmt::Display::fmt(self.syntax(), f)
621 }
622}
623impl fmt::Debug for QuotedString {
624 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625 f.debug_struct("QuotedString")
626 .field("open_quote", &support::DebugSyntaxToken(self.open_quote()))
627 .field("string", &support::DebugSyntaxToken(self.string()))
628 .field("close_quote", &support::DebugSyntaxToken(self.close_quote()))
629 .finish()
630 }
631}
632
633#[derive(Clone)]
634pub struct BlockString(SyntaxNode);
635impl AstNode for BlockString {
636 type Language = MicalLanguage;
637 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
638 kind == SyntaxKind::BLOCK_STRING
639 }
640 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
641 if Self::can_cast(node.kind()) {
642 Some(Self(node))
643 } else {
644 None
645 }
646 }
647 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
648 &self.0
649 }
650}
651impl BlockString {
652 pub fn header(&self) -> Option<BlockStringHeader> {
653 support::child(AstNode::syntax(self))
654 }
655 pub fn lines(&self) -> AstChildren<LineString> {
656 support::children(AstNode::syntax(self))
657 }
658}
659impl fmt::Display for BlockString {
660 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
661 fmt::Display::fmt(self.syntax(), f)
662 }
663}
664impl fmt::Debug for BlockString {
665 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
666 f.debug_struct("BlockString")
667 .field("header", &support::DebugAstNode(self.header()))
668 .field("lines", &support::DebugAstChildren(self.lines()))
669 .finish()
670 }
671}
672
673#[derive(Clone)]
674pub struct BlockStringHeader(SyntaxNode);
675impl AstNode for BlockStringHeader {
676 type Language = MicalLanguage;
677 fn can_cast(kind: <Self::Language as rowan::Language>::Kind) -> bool {
678 kind == SyntaxKind::BLOCK_STRING_HEADER
679 }
680 fn cast(node: rowan::SyntaxNode<Self::Language>) -> Option<Self> {
681 if Self::can_cast(node.kind()) {
682 Some(Self(node))
683 } else {
684 None
685 }
686 }
687 fn syntax(&self) -> &rowan::SyntaxNode<Self::Language> {
688 &self.0
689 }
690}
691impl BlockStringHeader {
692 pub fn style(&self) -> Option<SyntaxToken> {
693 self.syntax()
694 .children_with_tokens()
695 .filter_map(|it| it.into_token())
696 .find(|it| matches!(it.kind(), SyntaxKind::PIPE | SyntaxKind::GT))
697 }
698 pub fn chomp(&self) -> Option<SyntaxToken> {
699 self.syntax()
700 .children_with_tokens()
701 .filter_map(|it| it.into_token())
702 .find(|it| matches!(it.kind(), SyntaxKind::PLUS | SyntaxKind::MINUS))
703 }
704}
705impl fmt::Display for BlockStringHeader {
706 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707 fmt::Display::fmt(self.syntax(), f)
708 }
709}
710impl fmt::Debug for BlockStringHeader {
711 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
712 f.debug_struct("BlockStringHeader")
713 .field("style", &support::DebugSyntaxToken(self.style()))
714 .field("chomp", &support::DebugSyntaxToken(self.chomp()))
715 .finish()
716 }
717}