1pub mod binary;
2pub mod comments;
3pub mod cst;
4pub mod format_config;
5pub mod parser;
6pub mod parser_config;
7mod quotes;
8pub mod reference_literal;
9pub use reference_literal::{decode_reference_literal, encode_reference_literal};
10pub mod stream_parser;
11pub mod syntax;
12
13use comments::strip_comments;
14pub use cst::{CstKind, CstNode, parse_lino_to_cst, parse_lino_to_cst_with_config};
15use format_config::FormatConfig;
16pub use parser_config::ParserConfig;
17use std::borrow::Cow;
18pub use stream_parser::{
19 ErrorLocation, StreamIterator, StreamParseError, StreamParser, StreamPosition, StreamReference,
20};
21pub use syntax::{SyntaxReference, reference_quote};
22
23#[cfg(feature = "macro")]
25pub use links_notation_macro::lino;
26use std::error::Error as StdError;
27use std::fmt;
28
29pub const VERSION: &str = env!("CARGO_PKG_VERSION");
40
41#[derive(Debug)]
43pub enum ParseError {
44 EmptyInput,
46 SyntaxError(SyntaxError),
48 NestingTooDeep(NestingTooDeep),
51 InternalError(String),
53}
54
55impl fmt::Display for ParseError {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 match self {
58 ParseError::EmptyInput => write!(f, "Empty input"),
59 ParseError::SyntaxError(error) => write!(f, "Syntax error at {}", error),
60 ParseError::NestingTooDeep(error) => write!(f, "Nesting too deep at {}", error),
61 ParseError::InternalError(msg) => write!(f, "Internal error: {}", msg),
62 }
63 }
64}
65
66impl StdError for ParseError {}
67
68const QUOTED_LINE_WIDTH: usize = 80;
73
74const ELLIPSIS: &str = "...";
76
77#[derive(Debug, Clone, PartialEq, Eq)]
93pub struct SyntaxError {
94 pub offset: usize,
96 pub line: usize,
98 pub column: usize,
100 pub expected: Vec<String>,
103 pub found: Option<char>,
105 pub line_text: String,
107}
108
109impl SyntaxError {
110 pub fn summary(&self) -> String {
126 let found = match self.found {
127 Some(character) => format!("\"{}\"", character.escape_debug()),
128 None => "end of input".to_string(),
129 };
130 match join_alternatives(&self.expected) {
131 Some(expected) => format!(
132 "line {}, column {}: expected {}, found {}",
133 self.line, self.column, expected, found
134 ),
135 None => format!(
136 "line {}, column {}: unexpected {}",
137 self.line, self.column, found
138 ),
139 }
140 }
141
142 pub fn snippet(&self) -> String {
158 snippet(self.line, &self.line_text, self.column)
159 }
160}
161
162impl fmt::Display for SyntaxError {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 write!(f, "{}\n{}", self.summary(), self.snippet())
165 }
166}
167
168impl StdError for SyntaxError {}
169
170#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct NestingTooDeep {
194 pub max_depth: usize,
196 pub offset: usize,
198 pub line: usize,
200 pub column: usize,
202 pub line_text: String,
204}
205
206impl NestingTooDeep {
207 pub fn summary(&self) -> String {
209 format!(
210 "line {}, column {}: nesting depth exceeds the maximum of {}",
211 self.line, self.column, self.max_depth
212 )
213 }
214
215 pub fn snippet(&self) -> String {
217 snippet(self.line, &self.line_text, self.column)
218 }
219}
220
221impl fmt::Display for NestingTooDeep {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 write!(f, "{}\n{}", self.summary(), self.snippet())
224 }
225}
226
227impl StdError for NestingTooDeep {}
228
229fn snippet(number: usize, line_text: &str, column: usize) -> String {
232 let (quoted, column) = quote_line(line_text, column);
233 let number = number.to_string();
234 let gutter = " ".repeat(number.len());
235 format!(
236 "{} | {}\n{} | {}^",
237 number,
238 quoted,
239 gutter,
240 " ".repeat(column - 1)
241 )
242}
243
244fn join_alternatives(alternatives: &[String]) -> Option<String> {
246 match alternatives {
247 [] => None,
248 [only] => Some(only.clone()),
249 [rest @ .., last] => Some(format!("{} or {}", rest.join(", "), last)),
250 }
251}
252
253fn quote_line(line: &str, column: usize) -> (String, usize) {
256 let characters: Vec<char> = line.chars().collect();
257 if characters.len() <= QUOTED_LINE_WIDTH {
258 return (line.to_string(), column);
259 }
260
261 let target = column - 1;
262 let last_start = characters.len() - QUOTED_LINE_WIDTH;
263 let start = target.saturating_sub(QUOTED_LINE_WIDTH / 2).min(last_start);
264 let end = start + QUOTED_LINE_WIDTH;
265
266 let mut quoted = String::new();
267 if start > 0 {
268 quoted.push_str(ELLIPSIS);
269 }
270 quoted.extend(&characters[start..end]);
271 if end < characters.len() {
272 quoted.push_str(ELLIPSIS);
273 }
274
275 let shift = if start > 0 {
276 ELLIPSIS.chars().count()
277 } else {
278 0
279 };
280 (quoted, target - start + shift + 1)
281}
282
283fn locate(document: &str, failure: parser::ParseFailure) -> SyntaxError {
287 let offset = failure.offset.min(document.len());
288 let mut line = 1;
289 let mut line_start = 0;
290 let bytes = document.as_bytes();
291 let mut cursor = 0;
292 while cursor < offset {
293 match bytes[cursor] {
294 b'\r' => {
295 line += 1;
296 cursor += 1;
297 if cursor < offset && bytes[cursor] == b'\n' {
298 cursor += 1;
299 }
300 line_start = cursor;
301 }
302 b'\n' => {
303 line += 1;
304 cursor += 1;
305 line_start = cursor;
306 }
307 _ => cursor += 1,
308 }
309 }
310 let column = document[line_start..offset].chars().count() + 1;
311 let line_end = document[line_start..]
312 .find(['\r', '\n'])
313 .map_or(document.len(), |position| line_start + position);
314 let line_text = &document[line_start..line_end];
315
316 SyntaxError {
317 offset,
318 line,
319 column,
320 expected: failure.expected.iter().map(|s| s.to_string()).collect(),
321 found: document[offset..].chars().next(),
322 line_text: line_text.to_string(),
323 }
324}
325
326fn parse_error(document: &str, failure: parser::ParseFailure) -> ParseError {
328 let max_depth = failure.max_depth_exceeded;
329 let located = locate(document, failure);
330 match max_depth {
331 Some(max_depth) => ParseError::NestingTooDeep(NestingTooDeep {
332 max_depth,
333 offset: located.offset,
334 line: located.line,
335 column: located.column,
336 line_text: located.line_text,
337 }),
338 None => ParseError::SyntaxError(located),
339 }
340}
341
342#[derive(Debug, Clone, PartialEq)]
343pub enum LiNo<T> {
344 Link { id: Option<T>, values: Vec<Self> },
345 Ref(T),
346}
347
348impl<T> LiNo<T> {
349 pub fn is_ref(&self) -> bool {
350 matches!(self, LiNo::Ref(_))
351 }
352
353 pub fn is_link(&self) -> bool {
354 matches!(self, LiNo::Link { .. })
355 }
356
357 pub fn new(id: Option<T>, values: Vec<Self>) -> Self {
374 LiNo::Link { id, values }
375 }
376
377 pub fn anonymous(values: Vec<Self>) -> Self {
388 LiNo::Link { id: None, values }
389 }
390
391 pub fn reference(value: T) -> Self {
401 LiNo::Ref(value)
402 }
403}
404
405#[derive(Debug, Clone, Default)]
440pub struct LiNoBuilder {
441 id: Option<String>,
442 values: Vec<LiNo<String>>,
443}
444
445impl LiNoBuilder {
446 pub fn new() -> Self {
448 Self::default()
449 }
450
451 pub fn id(mut self, id: &str) -> Self {
455 self.id = Some(id.to_string());
456 self
457 }
458
459 pub fn value(mut self, value: &str) -> Self {
461 self.values.push(LiNo::Ref(value.to_string()));
462 self
463 }
464
465 pub fn lino(mut self, value: LiNo<String>) -> Self {
467 self.values.push(value);
468 self
469 }
470
471 pub fn values<I, S>(mut self, values: I) -> Self
473 where
474 I: IntoIterator<Item = S>,
475 S: AsRef<str>,
476 {
477 for v in values {
478 self.values.push(LiNo::Ref(v.as_ref().to_string()));
479 }
480 self
481 }
482
483 pub fn linos<I>(mut self, values: I) -> Self
485 where
486 I: IntoIterator<Item = LiNo<String>>,
487 {
488 self.values.extend(values);
489 self
490 }
491
492 pub fn build(self) -> LiNo<String> {
494 LiNo::Link {
495 id: self.id,
496 values: self.values,
497 }
498 }
499}
500
501#[deprecated(since = "0.3.0", note = "Use LiNoBuilder instead")]
503pub type LinkBuilder = LiNoBuilder;
504
505impl<T: ToString + Clone> LiNo<T> {
506 pub fn format_with_config(&self, config: &FormatConfig) -> String {
514 match self {
515 LiNo::Ref(value) => {
516 let escaped = escape_reference(&value.to_string());
517 if config.less_parentheses {
518 escaped
519 } else {
520 format!("({})", escaped)
521 }
522 }
523 LiNo::Link { id, values } => {
524 if id.is_none() && values.is_empty() {
526 return if config.less_parentheses {
527 String::new()
528 } else {
529 "()".to_string()
530 };
531 }
532
533 if values.is_empty() {
535 if let Some(id_val) = id {
536 let escaped_id = escape_reference(&id_val.to_string());
537 return if config.less_parentheses && !needs_parentheses(&id_val.to_string())
538 {
539 escaped_id
540 } else {
541 format!("({})", escaped_id)
542 };
543 }
544 return if config.less_parentheses {
545 String::new()
546 } else {
547 "()".to_string()
548 };
549 }
550
551 let mut should_indent = false;
553 if config.should_indent_by_ref_count(values.len()) {
554 should_indent = true;
555 } else {
556 let values_str = values
558 .iter()
559 .map(|v| format_value(v))
560 .collect::<Vec<_>>()
561 .join(" ");
562
563 let test_line = if let Some(id_val) = id {
564 let id_str = escape_reference(&id_val.to_string());
565 if config.less_parentheses {
566 format!("{}: {}", id_str, values_str)
567 } else {
568 format!("({}: {})", id_str, values_str)
569 }
570 } else if config.less_parentheses {
571 values_str.clone()
572 } else {
573 format!("({})", values_str)
574 };
575
576 if config.should_indent_by_length(&test_line) {
577 should_indent = true;
578 }
579 }
580
581 if should_indent && !config.prefer_inline {
583 return self.format_indented(config);
584 }
585
586 let values_str = values
588 .iter()
589 .map(|v| format_value(v))
590 .collect::<Vec<_>>()
591 .join(" ");
592
593 if id.is_none() {
595 if config.less_parentheses {
596 let all_simple = values.iter().all(|v| matches!(v, LiNo::Ref(_)));
598 if all_simple {
599 return values
600 .iter()
601 .map(|v| match v {
602 LiNo::Ref(r) => escape_reference(&r.to_string()),
603 _ => format_value(v),
604 })
605 .collect::<Vec<_>>()
606 .join(" ");
607 }
608 return values_str;
609 }
610 return format!("({})", values_str);
611 }
612
613 let id_str = escape_reference(&id.as_ref().unwrap().to_string());
615 let with_colon = format!("{}: {}", id_str, values_str);
616 if config.less_parentheses && !needs_parentheses(&id.as_ref().unwrap().to_string())
617 {
618 with_colon
619 } else {
620 format!("({})", with_colon)
621 }
622 }
623 }
624 }
625
626 fn format_indented(&self, config: &FormatConfig) -> String {
628 match self {
629 LiNo::Ref(value) => {
630 let escaped = escape_reference(&value.to_string());
631 format!("({})", escaped)
632 }
633 LiNo::Link { id, values } => {
634 if id.is_none() {
635 values
637 .iter()
638 .map(|v| format!("{}{}", config.indent_string, format_value(v)))
639 .collect::<Vec<_>>()
640 .join("\n")
641 } else {
642 let id_str = escape_reference(&id.as_ref().unwrap().to_string());
644 let mut lines = vec![format!("{}:", id_str)];
645 for v in values {
646 lines.push(format!("{}{}", config.indent_string, format_value(v)));
647 }
648 lines.join("\n")
649 }
650 }
651 }
652 }
653}
654
655impl<T: ToString> fmt::Display for LiNo<T> {
656 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
657 match self {
658 LiNo::Ref(value) => write!(f, "{}", escape_reference(&value.to_string())),
659 LiNo::Link { id, values } => {
660 let id_str = id
661 .as_ref()
662 .map(|id| format!("{}: ", escape_reference(&id.to_string())))
663 .unwrap_or_default();
664
665 if f.alternate() {
666 let lines = values
668 .iter()
669 .map(|value| {
670 match value {
673 LiNo::Ref(_) => format!("{}({})", id_str, value),
674 _ => format!("{}{}", id_str, value),
675 }
676 })
677 .collect::<Vec<_>>()
678 .join("\n");
679 write!(f, "{}", lines)
680 } else {
681 let values_str = values
682 .iter()
683 .map(|value| value.to_string())
684 .collect::<Vec<_>>()
685 .join(" ");
686 write!(f, "({}{})", id_str, values_str)
687 }
688 }
689 }
690 }
691}
692
693impl LiNo<SyntaxReference> {
694 pub fn into_values(self) -> LiNo<String> {
707 match self {
708 LiNo::Ref(reference) => LiNo::Ref(reference.value),
709 LiNo::Link { id, values } => LiNo::Link {
710 id: id.map(|id| id.value),
711 values: values.into_iter().map(LiNo::into_values).collect(),
712 },
713 }
714 }
715
716 pub fn raw_id(&self) -> Option<&str> {
730 match self {
731 LiNo::Ref(reference) => reference.raw.as_deref(),
732 LiNo::Link { id, .. } => id.as_ref().and_then(|id| id.raw.as_deref()),
733 }
734 }
735
736 pub fn quote(&self) -> Option<char> {
739 self.raw_id().and_then(reference_quote)
740 }
741}
742
743impl From<LiNo<SyntaxReference>> for LiNo<String> {
745 fn from(link: LiNo<SyntaxReference>) -> Self {
746 link.into_values()
747 }
748}
749
750impl From<parser::Link> for LiNo<String> {
752 fn from(link: parser::Link) -> Self {
753 if let Some(body) = &link.nested {
754 return transform_nested(body, &plain_id);
755 }
756 if link.values.is_empty() && link.children.is_empty() {
757 if let Some(id) = link.id {
758 LiNo::Ref(id)
759 } else {
760 LiNo::Link {
761 id: None,
762 values: vec![],
763 }
764 }
765 } else {
766 let values: Vec<LiNo<String>> = link.values.into_iter().map(|v| v.into()).collect();
767 LiNo::Link {
768 id: link.id,
769 values,
770 }
771 }
772 }
773}
774
775trait IdReader<T>: Fn(&parser::Link) -> Option<T> {}
778
779impl<T, F: Fn(&parser::Link) -> Option<T>> IdReader<T> for F {}
780
781fn plain_id(link: &parser::Link) -> Option<String> {
783 link.id.clone()
784}
785
786fn syntax_id(link: &parser::Link, document: &str) -> Option<SyntaxReference> {
790 let value = link.id.clone()?;
791 let raw = link
792 .id_span
793 .as_ref()
794 .and_then(|span| document.get(span.clone()))
795 .map(str::to_owned);
796 Some(SyntaxReference { value, raw })
797}
798
799fn transform_nested<T: Clone, F: IdReader<T>>(body: &[parser::Link], id: &F) -> LiNo<T> {
807 let links = flatten_links(body, id);
808 let wraps_single_group =
809 body.len() == 1 && body[0].nested.is_some() && body[0].children.is_empty();
810 if links.len() == 1 && !wraps_single_group {
811 return links.into_iter().next().unwrap();
812 }
813 LiNo::Link {
814 id: None,
815 values: links,
816 }
817}
818
819fn flatten_links<T: Clone, F: IdReader<T>>(links: &[parser::Link], id: &F) -> Vec<LiNo<T>> {
821 let mut result = vec![];
822
823 for link in links {
824 flatten_link_recursive(link, None, &mut result, id);
825 }
826
827 result
828}
829
830fn flatten_link_recursive<T: Clone, F: IdReader<T>>(
831 link: &parser::Link,
832 parent: Option<&LiNo<T>>,
833 result: &mut Vec<LiNo<T>>,
834 id: &F,
835) {
836 if link.is_indented_id
839 && link.id.is_some()
840 && link.values.is_empty()
841 && !link.children.is_empty()
842 {
843 let child_values: Vec<LiNo<T>> = link
844 .children
845 .iter()
846 .map(|child| transform_indented_value(child, id))
847 .collect();
848
849 let current = LiNo::Link {
850 id: id(link),
851 values: child_values,
852 };
853
854 let combined = if let Some(parent) = parent {
855 let wrapped_parent = match parent {
857 LiNo::Ref(ref_id) => LiNo::Link {
858 id: None,
859 values: vec![LiNo::Ref(ref_id.clone())],
860 },
861 link => link.clone(),
862 };
863
864 LiNo::Link {
865 id: None,
866 values: vec![wrapped_parent, current],
867 }
868 } else {
869 current
870 };
871
872 result.push(combined);
873 return; }
875
876 let current = if let Some(body) = &link.nested {
878 transform_nested(body, id)
879 } else if link.values.is_empty() {
880 if let Some(id) = id(link) {
881 LiNo::Ref(id)
882 } else {
883 LiNo::Link {
884 id: None,
885 values: vec![],
886 }
887 }
888 } else {
889 LiNo::Link {
890 id: id(link),
891 values: link
892 .values
893 .iter()
894 .map(|value| transform_value(value, id))
895 .collect(),
896 }
897 };
898
899 let combined = if let Some(parent) = parent {
901 let wrapped_parent = match parent {
903 LiNo::Ref(ref_id) => LiNo::Link {
904 id: None,
905 values: vec![LiNo::Ref(ref_id.clone())],
906 },
907 link => link.clone(),
908 };
909
910 let wrapped_current = match current {
912 LiNo::Ref(ref_id) => LiNo::Link {
913 id: None,
914 values: vec![LiNo::Ref(ref_id)],
915 },
916 link => link,
917 };
918
919 LiNo::Link {
920 id: None,
921 values: vec![wrapped_parent, wrapped_current],
922 }
923 } else {
924 current
925 };
926
927 if link.children.is_empty() {
931 result.push(combined);
932 return;
933 }
934 result.push(combined.clone());
935
936 for child in &link.children {
938 flatten_link_recursive(child, Some(&combined), result, id);
939 }
940}
941
942fn transform_value<T: Clone, F: IdReader<T>>(link: &parser::Link, id: &F) -> LiNo<T> {
944 if let Some(body) = &link.nested {
945 return transform_nested(body, id);
946 }
947 if link.values.is_empty() {
948 return match id(link) {
949 Some(id) => LiNo::Ref(id),
950 None => LiNo::Link {
951 id: None,
952 values: vec![],
953 },
954 };
955 }
956 LiNo::Link {
957 id: id(link),
958 values: link
959 .values
960 .iter()
961 .map(|value| transform_value(value, id))
962 .collect(),
963 }
964}
965
966fn transform_indented_value<T: Clone, F: IdReader<T>>(link: &parser::Link, id: &F) -> LiNo<T> {
968 let children: Vec<_> = link
969 .children
970 .iter()
971 .map(|child| transform_indented_value(child, id))
972 .collect();
973 if !children.is_empty() && link.is_indented_id && link.id.is_some() && link.values.is_empty() {
974 return LiNo::Link {
975 id: id(link),
976 values: children,
977 };
978 }
979 let current = transform_value(link, id);
980
981 if !children.is_empty() {
982 match current {
983 LiNo::Link { id, mut values } => {
984 values.extend(children);
985 LiNo::Link { id, values }
986 }
987 LiNo::Ref(id) => {
988 if link.nested.is_some() {
989 return LiNo::Link {
990 id: Some(id),
991 values: children,
992 };
993 }
994 let mut values = vec![LiNo::Ref(id)];
995 values.extend(children);
996 LiNo::Link { id: None, values }
997 }
998 }
999 } else if link.id.is_none() && link.nested.is_none() && link.values.len() == 1 {
1000 match current {
1001 LiNo::Link { id: None, values } => values.into_iter().next().unwrap(),
1002 value => value,
1003 }
1004 } else {
1005 current
1006 }
1007}
1008
1009fn prepare<'a>(document: &'a str, config: &ParserConfig) -> Cow<'a, str> {
1015 if config.comments {
1016 Cow::Owned(strip_comments(document))
1017 } else {
1018 Cow::Borrowed(document)
1019 }
1020}
1021
1022pub fn parse_lino(document: &str) -> Result<LiNo<String>, ParseError> {
1041 parse_lino_with_config(document, &ParserConfig::default())
1042}
1043
1044pub fn parse_lino_with_config(
1058 document: &str,
1059 config: &ParserConfig,
1060) -> Result<LiNo<String>, ParseError> {
1061 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1063 return Ok(LiNo::Link {
1064 id: None,
1065 values: vec![],
1066 });
1067 }
1068
1069 let prepared = prepare(document, config);
1070 match parser::parse_document_with_max_depth(&prepared, config.max_depth) {
1071 Ok(links) => {
1072 if links.is_empty() {
1073 Ok(LiNo::Link {
1074 id: None,
1075 values: vec![],
1076 })
1077 } else {
1078 let flattened = flatten_links(&links, &plain_id);
1080 Ok(LiNo::Link {
1081 id: None,
1082 values: flattened,
1083 })
1084 }
1085 }
1086 Err(failure) => Err(parse_error(document, failure)),
1087 }
1088}
1089
1090pub fn parse_lino_to_links(document: &str) -> Result<Vec<LiNo<String>>, ParseError> {
1104 parse_lino_to_links_with_config(document, &ParserConfig::default())
1105}
1106
1107pub fn parse_lino_to_links_with_config(
1118 document: &str,
1119 config: &ParserConfig,
1120) -> Result<Vec<LiNo<String>>, ParseError> {
1121 read_links(document, config, &plain_id)
1122}
1123
1124pub fn parse_lino_to_syntax_links(
1158 document: &str,
1159) -> Result<Vec<LiNo<SyntaxReference>>, ParseError> {
1160 parse_lino_to_syntax_links_with_config(document, &ParserConfig::default())
1161}
1162
1163pub fn parse_lino_to_syntax_links_with_config(
1176 document: &str,
1177 config: &ParserConfig,
1178) -> Result<Vec<LiNo<SyntaxReference>>, ParseError> {
1179 read_links(document, config, &|link| syntax_id(link, document))
1180}
1181
1182fn read_links<T: Clone, F: IdReader<T>>(
1185 document: &str,
1186 config: &ParserConfig,
1187 id: &F,
1188) -> Result<Vec<LiNo<T>>, ParseError> {
1189 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1191 return Ok(vec![]);
1192 }
1193
1194 let prepared = prepare(document, config);
1195 match parser::parse_document_with_max_depth(&prepared, config.max_depth) {
1196 Ok(links) => {
1197 if links.is_empty() {
1198 Ok(vec![])
1199 } else {
1200 let flattened = flatten_links(&links, id);
1202 Ok(flattened)
1203 }
1204 }
1205 Err(failure) => Err(parse_error(document, failure)),
1206 }
1207}
1208
1209pub(crate) fn check_document<'a>(
1213 document: &'a str,
1214 config: &ParserConfig,
1215) -> Result<Cow<'a, str>, ParseError> {
1216 let prepared = prepare(document, config);
1217 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1218 return Ok(prepared);
1219 }
1220 match parser::parse_document_with_max_depth(&prepared, config.max_depth) {
1221 Ok(_) => Ok(prepared),
1222 Err(failure) => Err(parse_error(document, failure)),
1223 }
1224}
1225
1226pub fn format_links(links: &[LiNo<String>]) -> String {
1229 links
1230 .iter()
1231 .map(|link| format!("{}", link))
1232 .collect::<Vec<_>>()
1233 .join("\n")
1234}
1235
1236pub fn format_links_with_config(links: &[LiNo<String>], config: &FormatConfig) -> String {
1246 if links.is_empty() {
1247 return String::new();
1248 }
1249
1250 let links_to_format = if config.group_consecutive {
1252 group_consecutive_links(links)
1253 } else {
1254 links.to_vec()
1255 };
1256
1257 links_to_format
1258 .iter()
1259 .map(|link| link.format_with_config(config))
1260 .collect::<Vec<_>>()
1261 .join("\n")
1262}
1263
1264fn group_consecutive_links(links: &[LiNo<String>]) -> Vec<LiNo<String>> {
1280 if links.is_empty() {
1281 return vec![];
1282 }
1283
1284 let mut grouped = vec![];
1285 let mut i = 0;
1286
1287 while i < links.len() {
1288 let current = &links[i];
1289
1290 if let LiNo::Link {
1292 id: Some(current_id),
1293 values: current_values,
1294 } = current
1295 {
1296 if !current_values.is_empty() {
1297 let mut same_id_values = current_values.clone();
1299 let mut j = i + 1;
1300
1301 while j < links.len() {
1302 if let LiNo::Link {
1303 id: Some(next_id),
1304 values: next_values,
1305 } = &links[j]
1306 {
1307 if next_id == current_id && !next_values.is_empty() {
1308 same_id_values.extend(next_values.clone());
1309 j += 1;
1310 } else {
1311 break;
1312 }
1313 } else {
1314 break;
1315 }
1316 }
1317
1318 if j > i + 1 {
1320 grouped.push(LiNo::Link {
1321 id: Some(current_id.clone()),
1322 values: same_id_values,
1323 });
1324 i = j;
1325 continue;
1326 }
1327 }
1328 }
1329
1330 grouped.push(current.clone());
1331 i += 1;
1332 }
1333
1334 grouped
1335}
1336
1337fn escape_reference(reference: &str) -> String {
1339 reference_literal::format_reference(reference)
1340}
1341
1342fn needs_parentheses(s: &str) -> bool {
1344 s.contains(' ') || s.contains(':') || s.contains('(') || s.contains(')')
1345}
1346
1347fn format_value<T: ToString>(value: &LiNo<T>) -> String {
1349 match value {
1350 LiNo::Ref(r) => escape_reference(&r.to_string()),
1351 LiNo::Link { id, values } => {
1352 if values.is_empty() {
1354 if let Some(id_val) = id {
1355 return escape_reference(&id_val.to_string());
1356 }
1357 return String::new();
1358 }
1359 format!("{}", value)
1361 }
1362 }
1363}
1364
1365macro_rules! impl_tuple_from {
1402 (@str_tuple 2, $t0:tt, $t1:tt) => {
1404 impl From<(&str, &str)> for LiNo<String> {
1405 fn from(tuple: (&str, &str)) -> Self {
1406 LiNo::Link {
1407 id: Some(tuple.$t0.to_string()),
1408 values: vec![LiNo::Ref(tuple.$t1.to_string())],
1409 }
1410 }
1411 }
1412 };
1413 (@string_tuple 2, $t0:tt, $t1:tt) => {
1414 impl From<(String, String)> for LiNo<String> {
1415 fn from(tuple: (String, String)) -> Self {
1416 LiNo::Link {
1417 id: Some(tuple.$t0),
1418 values: vec![LiNo::Ref(tuple.$t1)],
1419 }
1420 }
1421 }
1422 };
1423 (@str_lino_tuple 2, $t0:tt, $t1:tt) => {
1424 impl From<(&str, LiNo<String>)> for LiNo<String> {
1425 fn from(tuple: (&str, LiNo<String>)) -> Self {
1426 LiNo::Link {
1427 id: Some(tuple.$t0.to_string()),
1428 values: vec![tuple.$t1],
1429 }
1430 }
1431 }
1432 };
1433 (@lino_tuple 2, $t0:tt, $t1:tt) => {
1434 impl From<(LiNo<String>, LiNo<String>)> for LiNo<String> {
1435 fn from(tuple: (LiNo<String>, LiNo<String>)) -> Self {
1436 LiNo::Link {
1437 id: None,
1438 values: vec![tuple.$t0, tuple.$t1],
1439 }
1440 }
1441 }
1442 };
1443
1444 (@str_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1446 impl From<(&str, &str, &str)> for LiNo<String> {
1447 fn from(tuple: (&str, &str, &str)) -> Self {
1448 LiNo::Link {
1449 id: Some(tuple.$t0.to_string()),
1450 values: vec![LiNo::Ref(tuple.$t1.to_string()), LiNo::Ref(tuple.$t2.to_string())],
1451 }
1452 }
1453 }
1454 };
1455 (@string_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1456 impl From<(String, String, String)> for LiNo<String> {
1457 fn from(tuple: (String, String, String)) -> Self {
1458 LiNo::Link {
1459 id: Some(tuple.$t0),
1460 values: vec![LiNo::Ref(tuple.$t1), LiNo::Ref(tuple.$t2)],
1461 }
1462 }
1463 }
1464 };
1465 (@str_lino_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1466 impl From<(&str, LiNo<String>, LiNo<String>)> for LiNo<String> {
1467 fn from(tuple: (&str, LiNo<String>, LiNo<String>)) -> Self {
1468 LiNo::Link {
1469 id: Some(tuple.$t0.to_string()),
1470 values: vec![tuple.$t1, tuple.$t2],
1471 }
1472 }
1473 }
1474 };
1475 (@lino_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1476 impl From<(LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1477 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1478 LiNo::Link {
1479 id: None,
1480 values: vec![tuple.$t0, tuple.$t1, tuple.$t2],
1481 }
1482 }
1483 }
1484 };
1485
1486 (@str_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1488 impl From<(&str, &str, &str, &str)> for LiNo<String> {
1489 fn from(tuple: (&str, &str, &str, &str)) -> Self {
1490 LiNo::Link {
1491 id: Some(tuple.$t0.to_string()),
1492 values: vec![
1493 LiNo::Ref(tuple.$t1.to_string()),
1494 LiNo::Ref(tuple.$t2.to_string()),
1495 LiNo::Ref(tuple.$t3.to_string()),
1496 ],
1497 }
1498 }
1499 }
1500 };
1501 (@string_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1502 impl From<(String, String, String, String)> for LiNo<String> {
1503 fn from(tuple: (String, String, String, String)) -> Self {
1504 LiNo::Link {
1505 id: Some(tuple.$t0),
1506 values: vec![LiNo::Ref(tuple.$t1), LiNo::Ref(tuple.$t2), LiNo::Ref(tuple.$t3)],
1507 }
1508 }
1509 }
1510 };
1511 (@str_lino_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1512 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1513 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1514 LiNo::Link {
1515 id: Some(tuple.$t0.to_string()),
1516 values: vec![tuple.$t1, tuple.$t2, tuple.$t3],
1517 }
1518 }
1519 }
1520 };
1521 (@lino_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1522 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1523 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1524 LiNo::Link {
1525 id: None,
1526 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3],
1527 }
1528 }
1529 }
1530 };
1531
1532 (@str_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1534 impl From<(&str, &str, &str, &str, &str)> for LiNo<String> {
1535 fn from(tuple: (&str, &str, &str, &str, &str)) -> Self {
1536 LiNo::Link {
1537 id: Some(tuple.$t0.to_string()),
1538 values: vec![
1539 LiNo::Ref(tuple.$t1.to_string()),
1540 LiNo::Ref(tuple.$t2.to_string()),
1541 LiNo::Ref(tuple.$t3.to_string()),
1542 LiNo::Ref(tuple.$t4.to_string()),
1543 ],
1544 }
1545 }
1546 }
1547 };
1548 (@string_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1549 impl From<(String, String, String, String, String)> for LiNo<String> {
1550 fn from(tuple: (String, String, String, String, String)) -> Self {
1551 LiNo::Link {
1552 id: Some(tuple.$t0),
1553 values: vec![
1554 LiNo::Ref(tuple.$t1),
1555 LiNo::Ref(tuple.$t2),
1556 LiNo::Ref(tuple.$t3),
1557 LiNo::Ref(tuple.$t4),
1558 ],
1559 }
1560 }
1561 }
1562 };
1563 (@str_lino_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1564 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1565 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1566 LiNo::Link {
1567 id: Some(tuple.$t0.to_string()),
1568 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4],
1569 }
1570 }
1571 }
1572 };
1573 (@lino_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1574 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1575 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1576 LiNo::Link {
1577 id: None,
1578 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4],
1579 }
1580 }
1581 }
1582 };
1583
1584 (@str_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1586 impl From<(&str, &str, &str, &str, &str, &str)> for LiNo<String> {
1587 fn from(tuple: (&str, &str, &str, &str, &str, &str)) -> Self {
1588 LiNo::Link {
1589 id: Some(tuple.$t0.to_string()),
1590 values: vec![
1591 LiNo::Ref(tuple.$t1.to_string()),
1592 LiNo::Ref(tuple.$t2.to_string()),
1593 LiNo::Ref(tuple.$t3.to_string()),
1594 LiNo::Ref(tuple.$t4.to_string()),
1595 LiNo::Ref(tuple.$t5.to_string()),
1596 ],
1597 }
1598 }
1599 }
1600 };
1601 (@string_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1602 impl From<(String, String, String, String, String, String)> for LiNo<String> {
1603 fn from(tuple: (String, String, String, String, String, String)) -> Self {
1604 LiNo::Link {
1605 id: Some(tuple.$t0),
1606 values: vec![
1607 LiNo::Ref(tuple.$t1),
1608 LiNo::Ref(tuple.$t2),
1609 LiNo::Ref(tuple.$t3),
1610 LiNo::Ref(tuple.$t4),
1611 LiNo::Ref(tuple.$t5),
1612 ],
1613 }
1614 }
1615 }
1616 };
1617 (@str_lino_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1618 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1619 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1620 LiNo::Link {
1621 id: Some(tuple.$t0.to_string()),
1622 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5],
1623 }
1624 }
1625 }
1626 };
1627 (@lino_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1628 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1629 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1630 LiNo::Link {
1631 id: None,
1632 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5],
1633 }
1634 }
1635 }
1636 };
1637
1638 (@str_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1640 impl From<(&str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1641 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str)) -> Self {
1642 LiNo::Link {
1643 id: Some(tuple.$t0.to_string()),
1644 values: vec![
1645 LiNo::Ref(tuple.$t1.to_string()),
1646 LiNo::Ref(tuple.$t2.to_string()),
1647 LiNo::Ref(tuple.$t3.to_string()),
1648 LiNo::Ref(tuple.$t4.to_string()),
1649 LiNo::Ref(tuple.$t5.to_string()),
1650 LiNo::Ref(tuple.$t6.to_string()),
1651 ],
1652 }
1653 }
1654 }
1655 };
1656 (@string_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1657 impl From<(String, String, String, String, String, String, String)> for LiNo<String> {
1658 fn from(tuple: (String, String, String, String, String, String, String)) -> Self {
1659 LiNo::Link {
1660 id: Some(tuple.$t0),
1661 values: vec![
1662 LiNo::Ref(tuple.$t1),
1663 LiNo::Ref(tuple.$t2),
1664 LiNo::Ref(tuple.$t3),
1665 LiNo::Ref(tuple.$t4),
1666 LiNo::Ref(tuple.$t5),
1667 LiNo::Ref(tuple.$t6),
1668 ],
1669 }
1670 }
1671 }
1672 };
1673 (@str_lino_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1674 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1675 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1676 LiNo::Link {
1677 id: Some(tuple.$t0.to_string()),
1678 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6],
1679 }
1680 }
1681 }
1682 };
1683 (@lino_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1684 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1685 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1686 LiNo::Link {
1687 id: None,
1688 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6],
1689 }
1690 }
1691 }
1692 };
1693
1694 (@str_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1696 impl From<(&str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1697 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1698 LiNo::Link {
1699 id: Some(tuple.$t0.to_string()),
1700 values: vec![
1701 LiNo::Ref(tuple.$t1.to_string()),
1702 LiNo::Ref(tuple.$t2.to_string()),
1703 LiNo::Ref(tuple.$t3.to_string()),
1704 LiNo::Ref(tuple.$t4.to_string()),
1705 LiNo::Ref(tuple.$t5.to_string()),
1706 LiNo::Ref(tuple.$t6.to_string()),
1707 LiNo::Ref(tuple.$t7.to_string()),
1708 ],
1709 }
1710 }
1711 }
1712 };
1713 (@string_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1714 impl From<(String, String, String, String, String, String, String, String)> for LiNo<String> {
1715 fn from(tuple: (String, String, String, String, String, String, String, String)) -> Self {
1716 LiNo::Link {
1717 id: Some(tuple.$t0),
1718 values: vec![
1719 LiNo::Ref(tuple.$t1),
1720 LiNo::Ref(tuple.$t2),
1721 LiNo::Ref(tuple.$t3),
1722 LiNo::Ref(tuple.$t4),
1723 LiNo::Ref(tuple.$t5),
1724 LiNo::Ref(tuple.$t6),
1725 LiNo::Ref(tuple.$t7),
1726 ],
1727 }
1728 }
1729 }
1730 };
1731 (@str_lino_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1732 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1733 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1734 LiNo::Link {
1735 id: Some(tuple.$t0.to_string()),
1736 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7],
1737 }
1738 }
1739 }
1740 };
1741 (@lino_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1742 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1743 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1744 LiNo::Link {
1745 id: None,
1746 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7],
1747 }
1748 }
1749 }
1750 };
1751
1752 (@str_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1754 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1755 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1756 LiNo::Link {
1757 id: Some(tuple.$t0.to_string()),
1758 values: vec![
1759 LiNo::Ref(tuple.$t1.to_string()),
1760 LiNo::Ref(tuple.$t2.to_string()),
1761 LiNo::Ref(tuple.$t3.to_string()),
1762 LiNo::Ref(tuple.$t4.to_string()),
1763 LiNo::Ref(tuple.$t5.to_string()),
1764 LiNo::Ref(tuple.$t6.to_string()),
1765 LiNo::Ref(tuple.$t7.to_string()),
1766 LiNo::Ref(tuple.$t8.to_string()),
1767 ],
1768 }
1769 }
1770 }
1771 };
1772 (@string_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1773 impl From<(String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1774 fn from(tuple: (String, String, String, String, String, String, String, String, String)) -> Self {
1775 LiNo::Link {
1776 id: Some(tuple.$t0),
1777 values: vec![
1778 LiNo::Ref(tuple.$t1),
1779 LiNo::Ref(tuple.$t2),
1780 LiNo::Ref(tuple.$t3),
1781 LiNo::Ref(tuple.$t4),
1782 LiNo::Ref(tuple.$t5),
1783 LiNo::Ref(tuple.$t6),
1784 LiNo::Ref(tuple.$t7),
1785 LiNo::Ref(tuple.$t8),
1786 ],
1787 }
1788 }
1789 }
1790 };
1791 (@str_lino_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1792 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1793 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1794 LiNo::Link {
1795 id: Some(tuple.$t0.to_string()),
1796 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8],
1797 }
1798 }
1799 }
1800 };
1801 (@lino_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1802 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1803 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1804 LiNo::Link {
1805 id: None,
1806 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8],
1807 }
1808 }
1809 }
1810 };
1811
1812 (@str_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1814 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1815 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1816 LiNo::Link {
1817 id: Some(tuple.$t0.to_string()),
1818 values: vec![
1819 LiNo::Ref(tuple.$t1.to_string()),
1820 LiNo::Ref(tuple.$t2.to_string()),
1821 LiNo::Ref(tuple.$t3.to_string()),
1822 LiNo::Ref(tuple.$t4.to_string()),
1823 LiNo::Ref(tuple.$t5.to_string()),
1824 LiNo::Ref(tuple.$t6.to_string()),
1825 LiNo::Ref(tuple.$t7.to_string()),
1826 LiNo::Ref(tuple.$t8.to_string()),
1827 LiNo::Ref(tuple.$t9.to_string()),
1828 ],
1829 }
1830 }
1831 }
1832 };
1833 (@string_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1834 impl From<(String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1835 fn from(tuple: (String, String, String, String, String, String, String, String, String, String)) -> Self {
1836 LiNo::Link {
1837 id: Some(tuple.$t0),
1838 values: vec![
1839 LiNo::Ref(tuple.$t1),
1840 LiNo::Ref(tuple.$t2),
1841 LiNo::Ref(tuple.$t3),
1842 LiNo::Ref(tuple.$t4),
1843 LiNo::Ref(tuple.$t5),
1844 LiNo::Ref(tuple.$t6),
1845 LiNo::Ref(tuple.$t7),
1846 LiNo::Ref(tuple.$t8),
1847 LiNo::Ref(tuple.$t9),
1848 ],
1849 }
1850 }
1851 }
1852 };
1853 (@str_lino_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1854 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1855 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1856 LiNo::Link {
1857 id: Some(tuple.$t0.to_string()),
1858 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9],
1859 }
1860 }
1861 }
1862 };
1863 (@lino_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1864 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1865 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1866 LiNo::Link {
1867 id: None,
1868 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9],
1869 }
1870 }
1871 }
1872 };
1873
1874 (@str_tuple 11, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt) => {
1876 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1877 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1878 LiNo::Link {
1879 id: Some(tuple.$t0.to_string()),
1880 values: vec![
1881 LiNo::Ref(tuple.$t1.to_string()),
1882 LiNo::Ref(tuple.$t2.to_string()),
1883 LiNo::Ref(tuple.$t3.to_string()),
1884 LiNo::Ref(tuple.$t4.to_string()),
1885 LiNo::Ref(tuple.$t5.to_string()),
1886 LiNo::Ref(tuple.$t6.to_string()),
1887 LiNo::Ref(tuple.$t7.to_string()),
1888 LiNo::Ref(tuple.$t8.to_string()),
1889 LiNo::Ref(tuple.$t9.to_string()),
1890 LiNo::Ref(tuple.$t10.to_string()),
1891 ],
1892 }
1893 }
1894 }
1895 };
1896 (@string_tuple 11, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt) => {
1897 impl From<(String, String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1898 fn from(tuple: (String, String, String, String, String, String, String, String, String, String, String)) -> Self {
1899 LiNo::Link {
1900 id: Some(tuple.$t0),
1901 values: vec![
1902 LiNo::Ref(tuple.$t1),
1903 LiNo::Ref(tuple.$t2),
1904 LiNo::Ref(tuple.$t3),
1905 LiNo::Ref(tuple.$t4),
1906 LiNo::Ref(tuple.$t5),
1907 LiNo::Ref(tuple.$t6),
1908 LiNo::Ref(tuple.$t7),
1909 LiNo::Ref(tuple.$t8),
1910 LiNo::Ref(tuple.$t9),
1911 LiNo::Ref(tuple.$t10),
1912 ],
1913 }
1914 }
1915 }
1916 };
1917 (@str_lino_tuple 11, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt) => {
1918 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1919 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1920 LiNo::Link {
1921 id: Some(tuple.$t0.to_string()),
1922 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10],
1923 }
1924 }
1925 }
1926 };
1927 (@lino_tuple 11, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt) => {
1928 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1929 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1930 LiNo::Link {
1931 id: None,
1932 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10],
1933 }
1934 }
1935 }
1936 };
1937
1938 (@str_tuple 12, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt, $t11:tt) => {
1940 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1941 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1942 LiNo::Link {
1943 id: Some(tuple.$t0.to_string()),
1944 values: vec![
1945 LiNo::Ref(tuple.$t1.to_string()),
1946 LiNo::Ref(tuple.$t2.to_string()),
1947 LiNo::Ref(tuple.$t3.to_string()),
1948 LiNo::Ref(tuple.$t4.to_string()),
1949 LiNo::Ref(tuple.$t5.to_string()),
1950 LiNo::Ref(tuple.$t6.to_string()),
1951 LiNo::Ref(tuple.$t7.to_string()),
1952 LiNo::Ref(tuple.$t8.to_string()),
1953 LiNo::Ref(tuple.$t9.to_string()),
1954 LiNo::Ref(tuple.$t10.to_string()),
1955 LiNo::Ref(tuple.$t11.to_string()),
1956 ],
1957 }
1958 }
1959 }
1960 };
1961 (@string_tuple 12, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt, $t11:tt) => {
1962 impl From<(String, String, String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1963 fn from(tuple: (String, String, String, String, String, String, String, String, String, String, String, String)) -> Self {
1964 LiNo::Link {
1965 id: Some(tuple.$t0),
1966 values: vec![
1967 LiNo::Ref(tuple.$t1),
1968 LiNo::Ref(tuple.$t2),
1969 LiNo::Ref(tuple.$t3),
1970 LiNo::Ref(tuple.$t4),
1971 LiNo::Ref(tuple.$t5),
1972 LiNo::Ref(tuple.$t6),
1973 LiNo::Ref(tuple.$t7),
1974 LiNo::Ref(tuple.$t8),
1975 LiNo::Ref(tuple.$t9),
1976 LiNo::Ref(tuple.$t10),
1977 LiNo::Ref(tuple.$t11),
1978 ],
1979 }
1980 }
1981 }
1982 };
1983 (@str_lino_tuple 12, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt, $t11:tt) => {
1984 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1985 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1986 LiNo::Link {
1987 id: Some(tuple.$t0.to_string()),
1988 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10, tuple.$t11],
1989 }
1990 }
1991 }
1992 };
1993 (@lino_tuple 12, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt, $t10:tt, $t11:tt) => {
1994 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1995 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1996 LiNo::Link {
1997 id: None,
1998 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10, tuple.$t11],
1999 }
2000 }
2001 }
2002 };
2003
2004 (2) => {
2006 impl_tuple_from!(@str_tuple 2, 0, 1);
2007 impl_tuple_from!(@string_tuple 2, 0, 1);
2008 impl_tuple_from!(@str_lino_tuple 2, 0, 1);
2009 impl_tuple_from!(@lino_tuple 2, 0, 1);
2010 };
2011 (3) => {
2012 impl_tuple_from!(@str_tuple 3, 0, 1, 2);
2013 impl_tuple_from!(@string_tuple 3, 0, 1, 2);
2014 impl_tuple_from!(@str_lino_tuple 3, 0, 1, 2);
2015 impl_tuple_from!(@lino_tuple 3, 0, 1, 2);
2016 };
2017 (4) => {
2018 impl_tuple_from!(@str_tuple 4, 0, 1, 2, 3);
2019 impl_tuple_from!(@string_tuple 4, 0, 1, 2, 3);
2020 impl_tuple_from!(@str_lino_tuple 4, 0, 1, 2, 3);
2021 impl_tuple_from!(@lino_tuple 4, 0, 1, 2, 3);
2022 };
2023 (5) => {
2024 impl_tuple_from!(@str_tuple 5, 0, 1, 2, 3, 4);
2025 impl_tuple_from!(@string_tuple 5, 0, 1, 2, 3, 4);
2026 impl_tuple_from!(@str_lino_tuple 5, 0, 1, 2, 3, 4);
2027 impl_tuple_from!(@lino_tuple 5, 0, 1, 2, 3, 4);
2028 };
2029 (6) => {
2030 impl_tuple_from!(@str_tuple 6, 0, 1, 2, 3, 4, 5);
2031 impl_tuple_from!(@string_tuple 6, 0, 1, 2, 3, 4, 5);
2032 impl_tuple_from!(@str_lino_tuple 6, 0, 1, 2, 3, 4, 5);
2033 impl_tuple_from!(@lino_tuple 6, 0, 1, 2, 3, 4, 5);
2034 };
2035 (7) => {
2036 impl_tuple_from!(@str_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2037 impl_tuple_from!(@string_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2038 impl_tuple_from!(@str_lino_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2039 impl_tuple_from!(@lino_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2040 };
2041 (8) => {
2042 impl_tuple_from!(@str_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2043 impl_tuple_from!(@string_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2044 impl_tuple_from!(@str_lino_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2045 impl_tuple_from!(@lino_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2046 };
2047 (9) => {
2048 impl_tuple_from!(@str_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2049 impl_tuple_from!(@string_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2050 impl_tuple_from!(@str_lino_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2051 impl_tuple_from!(@lino_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2052 };
2053 (10) => {
2054 impl_tuple_from!(@str_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2055 impl_tuple_from!(@string_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2056 impl_tuple_from!(@str_lino_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2057 impl_tuple_from!(@lino_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2058 };
2059 (11) => {
2060 impl_tuple_from!(@str_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2061 impl_tuple_from!(@string_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2062 impl_tuple_from!(@str_lino_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2063 impl_tuple_from!(@lino_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2064 };
2065 (12) => {
2066 impl_tuple_from!(@str_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2067 impl_tuple_from!(@string_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2068 impl_tuple_from!(@str_lino_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2069 impl_tuple_from!(@lino_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2070 };
2071}
2072
2073impl_tuple_from!(2);
2076impl_tuple_from!(3);
2077impl_tuple_from!(4);
2078impl_tuple_from!(5);
2079impl_tuple_from!(6);
2080impl_tuple_from!(7);
2081impl_tuple_from!(8);
2082impl_tuple_from!(9);
2083impl_tuple_from!(10);
2084impl_tuple_from!(11);
2085impl_tuple_from!(12);
2086
2087impl From<Vec<&str>> for LiNo<String> {
2118 fn from(values: Vec<&str>) -> Self {
2119 LiNo::Link {
2120 id: None,
2121 values: values
2122 .into_iter()
2123 .map(|s| LiNo::Ref(s.to_string()))
2124 .collect(),
2125 }
2126 }
2127}
2128
2129impl From<Vec<String>> for LiNo<String> {
2131 fn from(values: Vec<String>) -> Self {
2132 LiNo::Link {
2133 id: None,
2134 values: values.into_iter().map(LiNo::Ref).collect(),
2135 }
2136 }
2137}
2138
2139impl From<Vec<LiNo<String>>> for LiNo<String> {
2141 fn from(values: Vec<LiNo<String>>) -> Self {
2142 LiNo::Link { id: None, values }
2143 }
2144}
2145
2146impl From<(&str, Vec<&str>)> for LiNo<String> {
2158 fn from((id, values): (&str, Vec<&str>)) -> Self {
2159 LiNo::Link {
2160 id: Some(id.to_string()),
2161 values: values
2162 .into_iter()
2163 .map(|s| LiNo::Ref(s.to_string()))
2164 .collect(),
2165 }
2166 }
2167}
2168
2169impl From<(String, Vec<String>)> for LiNo<String> {
2171 fn from((id, values): (String, Vec<String>)) -> Self {
2172 LiNo::Link {
2173 id: Some(id),
2174 values: values.into_iter().map(LiNo::Ref).collect(),
2175 }
2176 }
2177}
2178
2179impl From<(&str, Vec<LiNo<String>>)> for LiNo<String> {
2181 fn from((id, values): (&str, Vec<LiNo<String>>)) -> Self {
2182 LiNo::Link {
2183 id: Some(id.to_string()),
2184 values,
2185 }
2186 }
2187}
2188
2189impl From<(String, Vec<LiNo<String>>)> for LiNo<String> {
2191 fn from((id, values): (String, Vec<LiNo<String>>)) -> Self {
2192 LiNo::Link {
2193 id: Some(id),
2194 values,
2195 }
2196 }
2197}