1use std::collections::HashMap;
3use std::fmt;
4use std::ops::Range;
5
6use serde_json::Value;
7
8use crate::{parser::iter::BranchIter, trim::TrimHint};
9
10const WHITESPACE: &str = "~";
11const ROOT: &str = "@root";
12pub trait Slice<'source>: fmt::Display + fmt::Debug {
17 fn as_str(&self) -> &'source str;
19
20 fn source(&self) -> &'source str;
22}
23
24pub trait Lines {
28 fn lines(&self) -> &Range<usize>;
30
31 fn lines_mut(&mut self) -> &mut Range<usize>;
33
34 fn lines_end(&mut self, line: &usize) {
36 self.lines_mut().end = line.clone() + 1;
37 }
38}
39
40pub trait Element<'source> {
42 fn open(&self) -> &'source str;
44
45 fn close(&self) -> &'source str;
50
51 fn open_span(&self) -> &Range<usize>;
53
54 fn close_span(&self) -> &Option<Range<usize>>;
56
57 fn is_closed(&self) -> bool;
59
60 fn exit(&mut self, close: Range<usize>);
62
63 fn span(&self) -> Range<usize> {
66 if let Some(ref close) = self.close_span() {
67 self.open_span().start..close.end
68 } else {
69 self.open_span().clone()
70 }
71 }
72}
73
74#[derive(Eq, PartialEq)]
79pub enum Node<'source> {
80 Document(Document<'source>),
82 Text(Text<'source>),
84 Statement(Call<'source>),
86 Block(Block<'source>),
92 RawStatement(TextBlock<'source>),
95 RawComment(TextBlock<'source>),
97 Comment(TextBlock<'source>),
99 Link(Link<'source>),
101}
102
103impl Default for Node<'_> {
104 fn default() -> Self {
105 Node::Document(Document("", vec![]))
106 }
107}
108
109impl<'source> Node<'source> {
110 pub fn trim(&self) -> TrimHint {
112 TrimHint {
113 before: self.trim_before(),
114 after: self.trim_after(),
115 }
116 }
117
118 fn trim_before(&self) -> bool {
119 match *self {
120 Self::Document(_)
121 | Self::Text(_)
122 | Self::RawStatement(_)
123 | Self::RawComment(_)
124 | Self::Comment(_)
125 | Self::Link(_) => false,
126 Self::Statement(ref n) => n.trim_before(),
127 Self::Block(ref n) => n.trim_before(),
128 }
129 }
130
131 fn trim_after(&self) -> bool {
132 match *self {
133 Self::Document(_)
134 | Self::Text(_)
135 | Self::RawStatement(_)
136 | Self::RawComment(_)
137 | Self::Comment(_)
138 | Self::Link(_) => false,
139 Self::Statement(ref n) => n.trim_after(),
140 Self::Block(ref n) => n.trim_after(),
141 }
142 }
143
144 pub fn into_iter<'a>(&'a self) -> BranchIter<'a> {
146 BranchIter::new(self)
147 }
148}
149
150impl<'source> Slice<'source> for Node<'source> {
151 fn as_str(&self) -> &'source str {
152 match *self {
153 Self::Document(ref n) => n.as_str(),
154 Self::Text(ref n) => n.as_str(),
155 Self::Statement(ref n) => n.as_str(),
156 Self::Block(ref n) => n.as_str(),
157 Self::Link(ref n) => n.as_str(),
158 Self::RawStatement(ref n)
159 | Self::RawComment(ref n)
160 | Self::Comment(ref n) => n.as_str(),
161 }
162 }
163
164 fn source(&self) -> &'source str {
165 match *self {
166 Self::Document(ref n) => n.source(),
167 Self::Text(ref n) => n.source(),
168 Self::RawStatement(ref n) => n.source(),
169 Self::RawComment(ref n) => n.source(),
170 Self::Comment(ref n) => n.source(),
171 Self::Statement(ref n) => n.source(),
172 Self::Block(ref n) => n.source(),
173 Self::Link(ref n) => n.source(),
174 }
175 }
176}
177
178impl fmt::Display for Node<'_> {
179 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180 match *self {
181 Self::Document(ref n) => n.fmt(f),
182 Self::Text(ref n) => n.fmt(f),
183 Self::Statement(ref n) => n.fmt(f),
184 Self::Block(ref n) => n.fmt(f),
185 Self::Link(ref n) => n.fmt(f),
186 Self::RawStatement(ref n)
187 | Self::RawComment(ref n)
188 | Self::Comment(ref n) => n.fmt(f),
189 }
190 }
191}
192
193impl fmt::Debug for Node<'_> {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 match *self {
196 Self::Document(ref n) => fmt::Debug::fmt(n, f),
197 Self::Text(ref n) => fmt::Debug::fmt(n, f),
198 Self::Statement(ref n) => fmt::Debug::fmt(n, f),
199 Self::Block(ref n) => fmt::Debug::fmt(n, f),
200 Self::Link(ref n) => fmt::Debug::fmt(n, f),
201 Self::RawStatement(ref n)
202 | Self::RawComment(ref n)
203 | Self::Comment(ref n) => fmt::Debug::fmt(n, f),
204 }
205 }
206}
207
208#[derive(Eq, PartialEq)]
210pub struct Text<'source> {
211 source: &'source str,
212 span: Range<usize>,
213 line: Range<usize>,
214}
215
216impl<'source> Text<'source> {
217 pub fn new(
219 source: &'source str,
220 span: Range<usize>,
221 line: Range<usize>,
222 ) -> Self {
223 Self { source, span, line }
224 }
225}
226
227impl<'source> Lines for Text<'source> {
228 fn lines(&self) -> &Range<usize> {
229 &self.line
230 }
231
232 fn lines_mut(&mut self) -> &mut Range<usize> {
233 &mut self.line
234 }
235}
236
237impl<'source> Slice<'source> for Text<'source> {
238 fn as_str(&self) -> &'source str {
239 &self.source[self.span.start..self.span.end]
240 }
241
242 fn source(&self) -> &'source str {
243 self.source
244 }
245}
246
247impl fmt::Display for Text<'_> {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(f, "{}", self.as_str())
250 }
251}
252
253impl fmt::Debug for Text<'_> {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 f.debug_struct("Text")
256 .field("source", &self.as_str())
257 .field("span", &self.span)
258 .field("line", &self.line)
259 .finish()
260 }
261}
262
263#[derive(Eq, PartialEq)]
266pub struct TextBlock<'source> {
267 source: &'source str,
268 text: Text<'source>,
269 open: Range<usize>,
270 close: Range<usize>,
271}
272
273impl<'source> TextBlock<'source> {
274 pub fn new(
276 source: &'source str,
277 text: Text<'source>,
278 open: Range<usize>,
279 close: Range<usize>,
280 ) -> Self {
281 Self {
282 source,
283 text,
284 open,
285 close,
286 }
287 }
288}
289
290impl<'source> Slice<'source> for TextBlock<'source> {
291 fn as_str(&self) -> &'source str {
292 &self.source[self.open.start..self.close.end]
293 }
294
295 fn source(&self) -> &'source str {
296 self.source
297 }
298}
299
300impl<'source> Lines for TextBlock<'source> {
301 fn lines(&self) -> &Range<usize> {
302 self.text.lines()
303 }
304
305 fn lines_mut(&mut self) -> &mut Range<usize> {
306 self.text.lines_mut()
307 }
308}
309
310impl<'source> Into<Text<'source>> for TextBlock<'source> {
311 fn into(self) -> Text<'source> {
312 self.text
313 }
314}
315
316impl fmt::Display for TextBlock<'_> {
317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318 write!(f, "{}", self.as_str())
319 }
320}
321
322impl fmt::Debug for TextBlock<'_> {
323 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
324 f.debug_struct("TextBlock")
325 .field("source", &self.as_str())
326 .field("open", &self.open)
327 .field("close", &self.close)
328 .field("line", self.lines())
329 .finish()
330 }
331}
332
333#[derive(Debug, Eq, PartialEq)]
336pub enum RawIdType {
337 Single,
339 Double,
341 Array,
343}
344
345#[derive(Debug, Eq, PartialEq)]
347pub enum ComponentType {
348 Parent,
350 ThisKeyword,
352 ThisDotSlash,
354 Identifier,
356 LocalIdentifier,
358 RawIdentifier(RawIdType),
360 Delimiter,
362}
363
364#[derive(Eq, PartialEq)]
366pub struct Component<'source> {
367 source: &'source str,
368 kind: ComponentType,
369 span: Range<usize>,
370 value: Option<String>,
371}
372
373impl<'source> Component<'source> {
374 pub fn new(
380 source: &'source str,
381 kind: ComponentType,
382 span: Range<usize>,
383 value: Option<String>,
384 ) -> Self {
385 Self {
386 source,
387 kind,
388 span,
389 value,
390 }
391 }
392
393 pub fn is_root(&self) -> bool {
395 self.as_str() == ROOT
396 }
397
398 pub fn kind(&self) -> &ComponentType {
400 &self.kind
401 }
402
403 pub fn span(&self) -> &Range<usize> {
405 &self.span
406 }
407
408 pub fn is_local(&self) -> bool {
411 &ComponentType::LocalIdentifier == self.kind()
412 }
413
414 pub fn is_identifier(&self) -> bool {
416 &ComponentType::Identifier == self.kind()
417 }
418
419 pub fn is_explicit(&self) -> bool {
422 &ComponentType::ThisKeyword == self.kind()
423 || self.is_explicit_dot_slash()
424 }
425
426 pub fn is_explicit_dot_slash(&self) -> bool {
432 &ComponentType::ThisDotSlash == self.kind()
433 }
434
435 pub fn as_value(&self) -> &str {
447 if let Some(ref value) = self.value {
448 return value;
449 }
450 self.as_str()
451 }
452}
453
454impl<'source> Slice<'source> for Component<'source> {
455 fn as_str(&self) -> &'source str {
456 &self.source[self.span().start..self.span().end]
457 }
458
459 fn source(&self) -> &'source str {
460 self.source
461 }
462}
463
464impl fmt::Display for Component<'_> {
465 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
466 write!(f, "{}", self.as_str())
467 }
468}
469
470impl fmt::Debug for Component<'_> {
471 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
472 f.debug_struct("Component")
473 .field("source", &self.as_str())
474 .field("kind", &self.kind)
475 .field("span", &self.span)
476 .finish()
477 }
478}
479
480#[derive(Eq, PartialEq)]
482pub struct Path<'source> {
483 source: &'source str,
484 components: Vec<Component<'source>>,
485 parents: u8,
486 explicit: bool,
487 root: bool,
488 span: Range<usize>,
489 line: Range<usize>,
490 absolute: bool,
491}
492
493impl<'source> Path<'source> {
494 pub fn new(
496 source: &'source str,
497 span: Range<usize>,
498 line: Range<usize>,
499 ) -> Self {
500 Self {
501 source,
502 components: Vec::new(),
503 parents: 0,
504 explicit: false,
505 root: false,
506 span,
507 line,
508 absolute: false,
509 }
510 }
511
512 pub fn absolute(&self) -> bool {
517 self.absolute
518 }
519
520 pub fn set_absolute(&mut self, value: bool) {
522 self.absolute = value;
523 }
524
525 pub fn span(&self) -> &Range<usize> {
527 &self.span
528 }
529
530 pub fn span_mut(&mut self) -> &mut Range<usize> {
532 &mut self.span
533 }
534
535 pub fn add_component(&mut self, part: Component<'source>) {
537 self.components.push(part);
538 }
539
540 pub fn components(&self) -> &Vec<Component<'source>> {
542 &self.components
543 }
544
545 pub fn parents(&self) -> u8 {
547 self.parents
548 }
549
550 pub fn set_parents(&mut self, parents: u8) {
552 self.parents = parents;
553 }
554
555 pub fn is_root(&self) -> bool {
557 self.root
558 }
559
560 pub fn set_root(&mut self, root: bool) {
562 self.root = root;
563 }
564
565 pub fn is_explicit(&self) -> bool {
567 self.explicit
568 }
569
570 pub fn set_explicit(&mut self, explicit: bool) {
572 self.explicit = explicit;
573 }
574
575 pub fn is_empty(&self) -> bool {
577 self.components.is_empty()
578 }
579
580 pub fn is_local(&self) -> bool {
582 return !self.components.is_empty()
583 && self.components.first().unwrap().is_local();
584 }
585
586 pub fn is_simple(&self) -> bool {
588 return self.components.len() == 1
589 && self.components.first().unwrap().kind
590 == ComponentType::Identifier;
591 }
592}
593
594impl<'source> Slice<'source> for Path<'source> {
595 fn as_str(&self) -> &'source str {
596 &self.source[self.span.start..self.span.end]
597 }
598
599 fn source(&self) -> &'source str {
600 self.source
601 }
602}
603
604impl<'source> Lines for Path<'source> {
605 fn lines(&self) -> &Range<usize> {
606 &self.line
607 }
608
609 fn lines_mut(&mut self) -> &mut Range<usize> {
610 &mut self.line
611 }
612}
613
614impl fmt::Display for Path<'_> {
615 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616 write!(f, "{}", self.as_str())
617 }
618}
619
620impl fmt::Debug for Path<'_> {
621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622 f.debug_struct("Path")
623 .field("source", &self.as_str())
624 .field("components", &self.components)
625 .field("parents", &self.parents)
626 .field("explicit", &self.explicit)
627 .field("root", &self.root)
628 .field("line", &self.line)
629 .finish()
630 }
631}
632
633#[derive(Debug, Eq, PartialEq)]
635pub enum ParameterValue<'source> {
636 Path(Path<'source>),
638 Json {
640 source: &'source str,
642 value: Value,
644 span: Range<usize>,
646 line: Range<usize>,
648 },
649 SubExpr(Call<'source>),
651}
652
653impl<'source> From<(&'source str, Value, Range<usize>, Range<usize>)>
654 for ParameterValue<'source>
655{
656 fn from(value: (&'source str, Value, Range<usize>, Range<usize>)) -> Self {
657 ParameterValue::Json {
658 source: value.0,
659 value: value.1,
660 span: value.2,
661 line: value.3,
662 }
663 }
664}
665
666impl<'source> Slice<'source> for ParameterValue<'source> {
667 fn as_str(&self) -> &'source str {
668 match *self {
669 Self::Path(ref path) => path.as_str(),
670 Self::Json {
671 source, ref span, ..
672 } => &source[span.start..span.end],
673 Self::SubExpr(ref call) => call.as_str(),
674 }
675 }
676
677 fn source(&self) -> &'source str {
678 match *self {
679 Self::Path(ref path) => path.source(),
680 Self::Json { source, .. } => source,
681 Self::SubExpr(ref call) => call.source(),
682 }
683 }
684}
685
686impl<'source> Lines for ParameterValue<'source> {
687 fn lines(&self) -> &Range<usize> {
688 match *self {
689 ParameterValue::Path(ref path) => path.lines(),
690 ParameterValue::Json { ref line, .. } => line,
691 ParameterValue::SubExpr(ref call) => call.lines(),
692 }
693 }
694
695 fn lines_mut(&mut self) -> &mut Range<usize> {
696 match *self {
697 ParameterValue::Path(ref mut path) => path.lines_mut(),
698 ParameterValue::Json { ref mut line, .. } => line,
699 ParameterValue::SubExpr(ref mut call) => call.lines_mut(),
700 }
701 }
702}
703
704impl fmt::Display for ParameterValue<'_> {
705 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
706 write!(f, "{}", self.as_str())
707 }
708}
709
710#[derive(Debug, Eq, PartialEq)]
714pub enum CallTarget<'source> {
715 Path(Path<'source>),
717 SubExpr(Box<Call<'source>>),
719}
720
721impl<'source> CallTarget<'source> {
722 pub fn is_empty(&self) -> bool {
724 match *self {
725 Self::Path(ref path) => path.is_empty(),
726 Self::SubExpr(ref call) => call.is_empty(),
727 }
728 }
729
730 pub fn span(&self) -> &Range<usize> {
735 match *self {
736 Self::Path(ref path) => path.span(),
737 Self::SubExpr(ref call) => call.open_span(),
738 }
739 }
740}
741
742impl<'source> Slice<'source> for CallTarget<'source> {
743 fn as_str(&self) -> &'source str {
744 match *self {
745 Self::Path(ref path) => path.as_str(),
746 Self::SubExpr(ref call) => call.as_str(),
747 }
748 }
749
750 fn source(&self) -> &'source str {
751 match *self {
752 Self::Path(ref path) => path.source(),
753 Self::SubExpr(ref call) => call.source(),
754 }
755 }
756}
757
758impl<'source> Lines for CallTarget<'source> {
759 fn lines(&self) -> &Range<usize> {
760 match *self {
761 Self::Path(ref path) => path.lines(),
762 Self::SubExpr(ref call) => call.lines(),
763 }
764 }
765
766 fn lines_mut(&mut self) -> &mut Range<usize> {
767 match *self {
768 Self::Path(ref mut path) => path.lines_mut(),
769 Self::SubExpr(ref mut call) => call.lines_mut(),
770 }
771 }
772}
773
774impl fmt::Display for CallTarget<'_> {
775 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
776 write!(f, "{}", self.as_str())
777 }
778}
779
780impl Default for CallTarget<'_> {
781 fn default() -> Self {
782 CallTarget::Path(Path::new("", 0..0, 0..0))
783 }
784}
785
786#[derive(Default, Eq, PartialEq)]
794pub struct Call<'source> {
795 source: &'source str,
797 partial: bool,
798 conditional: bool,
799 open: Range<usize>,
800 close: Option<Range<usize>>,
801 target: CallTarget<'source>,
802 arguments: Vec<ParameterValue<'source>>,
803 parameters: HashMap<&'source str, ParameterValue<'source>>,
804 line: Range<usize>,
805}
806
807impl<'source> Call<'source> {
808 pub fn new(
813 source: &'source str,
814 open: Range<usize>,
815 line: Range<usize>,
816 ) -> Self {
817 Self {
818 source,
819 partial: false,
820 conditional: false,
821 open,
822 close: None,
823 target: CallTarget::Path(Path::new(source, 0..0, 0..0)),
824 arguments: Vec::new(),
825 parameters: HashMap::new(),
826 line,
827 }
828 }
829
830 pub fn is_empty(&self) -> bool {
832 self.target.is_empty()
833 }
834
835 pub fn target(&self) -> &CallTarget<'source> {
837 &self.target
838 }
839
840 pub fn has_target(&self) -> bool {
842 self.target.as_str() != ""
843 }
844
845 pub fn set_target(&mut self, target: CallTarget<'source>) {
847 self.target = target;
848 }
849
850 pub fn add_argument(&mut self, arg: ParameterValue<'source>) {
852 self.arguments.push(arg);
853 }
854
855 pub fn arguments(&self) -> &Vec<ParameterValue<'source>> {
857 &self.arguments
858 }
859
860 pub fn add_parameter(
862 &mut self,
863 key: &'source str,
864 val: ParameterValue<'source>,
865 ) {
866 self.parameters.insert(key, val);
867 }
868
869 pub fn parameters(
871 &self,
872 ) -> &HashMap<&'source str, ParameterValue<'source>> {
873 &self.parameters
874 }
875
876 pub fn is_partial(&self) -> bool {
878 self.partial
879 }
880
881 pub fn set_partial(&mut self, partial: bool) {
883 self.partial = partial;
884 }
885
886 pub fn is_conditional(&self) -> bool {
888 self.conditional
889 }
890
891 pub fn set_conditional(&mut self, conditional: bool) {
893 self.conditional = conditional;
894 }
895
896 pub fn is_escaped(&self) -> bool {
898 !self.open().starts_with("{{{")
900 }
901
902 fn trim_before(&self) -> bool {
903 self.open().ends_with(WHITESPACE)
904 }
905
906 fn trim_after(&self) -> bool {
907 self.close().starts_with(WHITESPACE)
908 }
909}
910
911impl<'source> Slice<'source> for Call<'source> {
912 fn as_str(&self) -> &'source str {
913 if let Some(ref close) = self.close {
914 return &self.source[self.open.start..close.end];
915 }
916 &self.source[self.open.start..self.open.end]
917 }
918
919 fn source(&self) -> &'source str {
920 self.source
921 }
922}
923
924impl<'source> Lines for Call<'source> {
925 fn lines(&self) -> &Range<usize> {
926 &self.line
927 }
928
929 fn lines_mut(&mut self) -> &mut Range<usize> {
930 &mut self.line
931 }
932}
933
934impl<'source> Element<'source> for Call<'source> {
935 fn open(&self) -> &'source str {
936 &self.source[self.open.start..self.open.end]
937 }
938
939 fn close(&self) -> &'source str {
940 if let Some(ref close) = self.close {
941 return &self.source[close.start..close.end];
942 }
943 ""
944 }
945
946 fn open_span(&self) -> &Range<usize> {
947 &self.open
948 }
949
950 fn close_span(&self) -> &Option<Range<usize>> {
951 &self.close
952 }
953
954 fn is_closed(&self) -> bool {
955 self.close.is_some()
956 }
957
958 fn exit(&mut self, close: Range<usize>) {
959 self.close = Some(close);
960 }
961}
962
963impl fmt::Display for Call<'_> {
964 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
965 write!(f, "{}", self.as_str())
966 }
967}
968
969impl fmt::Debug for Call<'_> {
970 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971 f.debug_struct("Call")
972 .field("source", &self.as_str())
973 .field("partial", &self.partial)
974 .field("open", &self.open)
975 .field("close", &self.close)
976 .field("target", &self.target)
977 .field("arguments", &self.arguments)
978 .field("parameters", &self.parameters)
979 .finish()
980 }
981}
982
983#[derive(Eq, PartialEq)]
988pub struct Document<'source>(pub &'source str, pub Vec<Node<'source>>);
989
990impl<'source> Document<'source> {
991 pub fn nodes(&self) -> &Vec<Node<'source>> {
993 &self.1
994 }
995
996 pub fn nodes_mut(&mut self) -> &mut Vec<Node<'source>> {
998 &mut self.1
999 }
1000}
1001
1002impl<'source> Slice<'source> for Document<'source> {
1003 fn as_str(&self) -> &'source str {
1004 self.0
1005 }
1006 fn source(&self) -> &'source str {
1007 self.0
1008 }
1009}
1010
1011impl fmt::Display for Document<'_> {
1012 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1013 write!(f, "{}", self.as_str())
1014 }
1015}
1016
1017impl fmt::Debug for Document<'_> {
1018 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1019 f.debug_struct("Document").field("nodes", &self.1).finish()
1020 }
1021}
1022
1023#[derive(Eq, PartialEq)]
1031pub struct Block<'source> {
1032 source: &'source str,
1033 nodes: Vec<Node<'source>>,
1034 raw: bool,
1035 open: Range<usize>,
1036 close: Option<Range<usize>>,
1037 call: Call<'source>,
1038 conditionals: Vec<Node<'source>>,
1039 line: Range<usize>,
1040}
1041
1042impl<'source> Block<'source> {
1043 pub fn new(
1045 source: &'source str,
1046 open: Range<usize>,
1047 raw: bool,
1048 line: Range<usize>,
1049 ) -> Self {
1050 Self {
1051 source,
1052 nodes: Vec::new(),
1053 raw,
1054 open,
1055 close: None,
1056 call: Default::default(),
1057 conditionals: Vec::new(),
1058 line,
1059 }
1060 }
1061
1062 pub fn call(&self) -> &Call<'source> {
1064 &self.call
1065 }
1066
1067 pub fn set_call(&mut self, call: Call<'source>) {
1069 self.call = call;
1070 }
1071
1072 pub fn name(&self) -> Option<&'source str> {
1077 match self.call.target() {
1078 CallTarget::Path(ref path) => {
1079 if path.is_simple() {
1080 let id = path.components().first().unwrap();
1081 Some(id.as_str())
1082 } else {
1083 None
1084 }
1085 }
1086 CallTarget::SubExpr(_) => None,
1087 }
1088 }
1089
1090 pub fn is_raw(&self) -> bool {
1092 self.raw
1093 }
1094
1095 pub fn add_condition(&mut self, condition: Block<'source>) {
1097 self.close_condition(condition.call.open.clone());
1098 self.conditionals.push(Node::Block(condition));
1099 }
1100
1101 pub fn conditions(&self) -> &Vec<Node<'source>> {
1103 &self.conditionals
1104 }
1105
1106 pub fn push(&mut self, node: Node<'source>) {
1109 if !self.conditionals.is_empty() {
1110 let mut last = self.conditionals.last_mut().unwrap();
1111 match &mut last {
1112 Node::Block(ref mut condition) => {
1113 condition.nodes.push(node);
1114 }
1115 _ => {}
1116 }
1117 } else {
1118 self.nodes.push(node);
1119 }
1120 }
1121
1122 pub fn nodes(&self) -> &'source Vec<Node> {
1126 &self.nodes
1127 }
1128
1129 pub fn trim_close(&self) -> TrimHint {
1131 TrimHint {
1132 before: self.trim_before_close(),
1133 after: self.trim_after_close(),
1134 }
1135 }
1136
1137 fn close_condition(&mut self, span: Range<usize>) {
1138 if !self.conditionals.is_empty() {
1139 if span.start > 0 {
1140 let close = span.start - 1..span.start;
1141 let mut last = self.conditionals.last_mut().unwrap();
1142 match &mut last {
1143 Node::Block(ref mut condition) => {
1144 condition.close = Some(close);
1145 }
1146 _ => {}
1147 }
1148 }
1149 }
1150 }
1151
1152 fn trim_before(&self) -> bool {
1153 let open = self.open();
1154 if self.is_raw() {
1155 open.len() > 4 && WHITESPACE == &open[4..5]
1156 } else {
1157 open.len() > 2 && WHITESPACE == &open[2..3]
1158 }
1159 }
1160
1161 fn trim_after(&self) -> bool {
1162 self.call.trim_after()
1163 }
1164
1165 fn trim_before_close(&self) -> bool {
1166 let close = self.close();
1167 if self.is_raw() {
1168 close.len() > 4 && WHITESPACE == &close[4..5]
1169 } else {
1170 close.len() > 2 && WHITESPACE == &close[2..3]
1171 }
1172 }
1173
1174 fn trim_after_close(&self) -> bool {
1175 let close = self.close();
1176
1177 if self.is_raw() {
1178 if close.len() > 5 {
1179 let index = close.len() - 5;
1180 close.len() > 4 && WHITESPACE == &close[index..index + 1]
1181 } else {
1182 false
1183 }
1184 } else {
1185 if close.len() > 3 {
1186 let index = close.len() - 3;
1187 close.len() > 2 && WHITESPACE == &close[index..index + 1]
1188 } else {
1189 false
1190 }
1191 }
1192 }
1193}
1194
1195impl<'source> Slice<'source> for Block<'source> {
1196 fn as_str(&self) -> &'source str {
1197 let close = self.close.clone().unwrap_or(0..self.source.len());
1198 &self.source[self.open.start..close.end]
1199 }
1200
1201 fn source(&self) -> &'source str {
1202 self.source
1203 }
1204}
1205
1206impl<'source> Lines for Block<'source> {
1207 fn lines(&self) -> &Range<usize> {
1208 &self.line
1209 }
1210
1211 fn lines_mut(&mut self) -> &mut Range<usize> {
1212 &mut self.line
1213 }
1214}
1215
1216impl<'source> Element<'source> for Block<'source> {
1217 fn open(&self) -> &'source str {
1218 &self.source[self.open.start..self.open.end]
1219 }
1220
1221 fn close(&self) -> &'source str {
1222 if let Some(ref close) = self.close {
1223 &self.source[close.start..close.end]
1224 } else {
1225 ""
1226 }
1227 }
1228
1229 fn open_span(&self) -> &Range<usize> {
1230 &self.open
1231 }
1232
1233 fn close_span(&self) -> &Option<Range<usize>> {
1234 &self.close
1235 }
1236
1237 fn is_closed(&self) -> bool {
1238 self.close.is_some()
1239 }
1240
1241 fn exit(&mut self, span: Range<usize>) {
1242 if !self.conditionals.is_empty() {
1247 let mut last = self.conditionals.last_mut().unwrap();
1248 match &mut last {
1249 Node::Block(ref mut condition) => {
1250 condition.close = Some(span.clone());
1251 }
1252 _ => {}
1253 }
1254 }
1255
1256 self.close = Some(span);
1257 }
1258}
1259
1260impl fmt::Display for Block<'_> {
1261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1262 for t in self.nodes() {
1263 t.fmt(f)?;
1264 }
1265 Ok(())
1266 }
1267}
1268
1269impl fmt::Debug for Block<'_> {
1270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1271 f.debug_struct("Block")
1272 .field("line", &self.line)
1273 .field("open", &self.open)
1274 .field("close", &self.close)
1275 .field("call", &self.call)
1276 .field("nodes", &self.nodes)
1277 .finish()
1278 }
1279}
1280
1281#[derive(Eq, PartialEq)]
1283pub struct Link<'source> {
1284 source: &'source str,
1285 open: Range<usize>,
1286 close: Option<Range<usize>>,
1287 line: Range<usize>,
1288 href_span: Range<usize>,
1289 label_span: Range<usize>,
1290 title_span: Range<usize>,
1291
1292 href: Option<String>,
1294 label: Option<String>,
1295 title: Option<String>,
1296}
1297
1298impl<'source> Link<'source> {
1299 pub fn new(
1301 source: &'source str,
1302 open: Range<usize>,
1303 line: Range<usize>,
1304 ) -> Self {
1305 Self {
1306 source,
1307 href_span: open.end..open.end,
1308 label_span: open.end..open.end,
1309 title_span: open.end..open.end,
1310 open,
1311 line,
1312 close: None,
1313 href: None,
1314 label: None,
1315 title: None,
1316 }
1317 }
1318
1319 pub fn href(&self) -> &str {
1323 if let Some(ref href) = self.href {
1324 return href;
1325 }
1326 &self.source[self.href_span.start..self.href_span.end]
1327 }
1328
1329 pub fn label(&self) -> &str {
1333 let lbl = if let Some(ref label) = self.label {
1334 return label;
1335 } else {
1336 &self.source[self.label_span.start..self.label_span.end]
1337 };
1338
1339 lbl
1340 }
1341
1342 pub fn title(&self) -> &str {
1346 let title = if let Some(ref title) = self.title {
1347 return title;
1348 } else {
1349 &self.source[self.title_span.start..self.title_span.end]
1350 };
1351
1352 title
1353 }
1354
1355 pub fn href_span(&self) -> &Range<usize> {
1357 &self.href_span
1358 }
1359
1360 pub fn label_span(&self) -> &Range<usize> {
1362 &self.label_span
1363 }
1364
1365 pub fn title_span(&self) -> &Range<usize> {
1367 &self.title_span
1368 }
1369
1370 pub fn href_end(&mut self, end: usize) {
1372 self.href_span.end = end;
1373 }
1374
1375 pub fn label_start(&mut self, start: usize) {
1377 self.label_span.start = start;
1378 }
1379
1380 pub fn label_end(&mut self, end: usize) {
1382 self.label_span.end = end;
1383 }
1384
1385 pub fn title_start(&mut self, start: usize) {
1387 self.title_span.start = start;
1388 }
1389
1390 pub fn title_end(&mut self, end: usize) {
1392 self.title_span.end = end;
1393 }
1394
1395 pub fn set_href(&mut self, value: String) {
1400 self.href = Some(value);
1401 }
1402
1403 pub fn set_label(&mut self, value: String) {
1408 self.label = Some(value);
1409 }
1410
1411 pub fn set_title(&mut self, value: String) {
1416 self.title = Some(value);
1417 }
1418
1419 pub fn is_escaped(&self) -> bool {
1421 self.open().starts_with("\\")
1422 }
1423
1424 pub(crate) fn after_escape(&self) -> &'source str {
1426 let close = self.close.clone().unwrap_or(0..self.open.len());
1427 &self.source[self.open.start + 1..close.end]
1428 }
1429}
1430
1431impl<'source> Slice<'source> for Link<'source> {
1432 fn as_str(&self) -> &'source str {
1433 let close = self.close.clone().unwrap_or(0..self.open.len());
1434 &self.source[self.open.start..close.end]
1435 }
1436
1437 fn source(&self) -> &'source str {
1438 self.source
1439 }
1440}
1441
1442impl<'source> Lines for Link<'source> {
1443 fn lines(&self) -> &Range<usize> {
1444 &self.line
1445 }
1446
1447 fn lines_mut(&mut self) -> &mut Range<usize> {
1448 &mut self.line
1449 }
1450}
1451
1452impl<'source> Element<'source> for Link<'source> {
1453 fn open(&self) -> &'source str {
1454 &self.source[self.open.start..self.open.end]
1455 }
1456
1457 fn close(&self) -> &'source str {
1458 if let Some(ref close) = self.close {
1459 &self.source[close.start..close.end]
1460 } else {
1461 ""
1462 }
1463 }
1464
1465 fn open_span(&self) -> &Range<usize> {
1466 &self.open
1467 }
1468
1469 fn close_span(&self) -> &Option<Range<usize>> {
1470 &self.close
1471 }
1472
1473 fn is_closed(&self) -> bool {
1474 self.close.is_some()
1475 }
1476
1477 fn exit(&mut self, span: Range<usize>) {
1478 self.close = Some(span);
1479 }
1480}
1481
1482impl fmt::Display for Link<'_> {
1483 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1484 write!(f, "{}", self.as_str())
1485 }
1486}
1487
1488impl fmt::Debug for Link<'_> {
1489 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1490 f.debug_struct("Link")
1491 .field("open", &self.open)
1492 .field("close", &self.close)
1493 .field("href", &self.href)
1494 .field("label", &self.label)
1495 .finish()
1496 }
1497}