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 "()".to_string();
527 }
528
529 if values.is_empty() {
531 if let Some(id_val) = id {
532 let escaped_id = escape_reference(&id_val.to_string());
533 return if config.less_parentheses && !needs_parentheses(&id_val.to_string())
534 {
535 escaped_id
536 } else {
537 format!("({})", escaped_id)
538 };
539 }
540 return "()".to_string();
541 }
542
543 let mut should_indent = false;
545 if config.should_indent_by_ref_count(values.len()) {
546 should_indent = true;
547 } else {
548 let values_str = values
550 .iter()
551 .map(|v| format_value(v))
552 .collect::<Vec<_>>()
553 .join(" ");
554
555 let test_line = if let Some(id_val) = id {
556 let id_str = escape_reference(&id_val.to_string());
557 if config.less_parentheses {
558 format!("{}: {}", id_str, values_str)
559 } else {
560 format!("({}: {})", id_str, values_str)
561 }
562 } else if config.less_parentheses && !has_lone_nested_value(values) {
563 values_str.clone()
564 } else {
565 format!("({})", values_str)
566 };
567
568 if config.should_indent_by_length(&test_line) {
569 should_indent = true;
570 }
571 }
572
573 if should_indent && !config.prefer_inline {
575 return self.format_indented(config);
576 }
577
578 let values_str = values
580 .iter()
581 .map(|v| format_value(v))
582 .collect::<Vec<_>>()
583 .join(" ");
584
585 if id.is_none() {
587 if config.less_parentheses && !has_lone_nested_value(values) {
588 let all_simple = values.iter().all(|v| matches!(v, LiNo::Ref(_)));
590 if all_simple {
591 return values
592 .iter()
593 .map(|v| match v {
594 LiNo::Ref(r) => escape_reference(&r.to_string()),
595 _ => format_value(v),
596 })
597 .collect::<Vec<_>>()
598 .join(" ");
599 }
600 return values_str;
601 }
602 return format!("({})", values_str);
603 }
604
605 let id_str = escape_reference(&id.as_ref().unwrap().to_string());
607 let with_colon = format!("{}: {}", id_str, values_str);
608 if config.less_parentheses && !needs_parentheses(&id.as_ref().unwrap().to_string())
609 {
610 with_colon
611 } else {
612 format!("({})", with_colon)
613 }
614 }
615 }
616 }
617
618 fn format_indented(&self, config: &FormatConfig) -> String {
620 match self {
621 LiNo::Ref(value) => {
622 let escaped = escape_reference(&value.to_string());
623 format!("({})", escaped)
624 }
625 LiNo::Link { id, values } => {
626 if id.is_none() {
627 values
629 .iter()
630 .map(|v| format!("{}{}", config.indent_string, format_value(v)))
631 .collect::<Vec<_>>()
632 .join("\n")
633 } else {
634 let id_str = escape_reference(&id.as_ref().unwrap().to_string());
636 let mut lines = vec![format!("{}:", id_str)];
637 for v in values {
638 lines.push(format!("{}{}", config.indent_string, format_value(v)));
639 }
640 lines.join("\n")
641 }
642 }
643 }
644 }
645}
646
647impl<T: ToString> fmt::Display for LiNo<T> {
648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
649 match self {
650 LiNo::Ref(value) => write!(f, "{}", escape_reference(&value.to_string())),
651 LiNo::Link { id, values } => {
652 let id_str = id
653 .as_ref()
654 .map(|id| format!("{}: ", escape_reference(&id.to_string())))
655 .unwrap_or_default();
656
657 if f.alternate() {
658 let lines = values
660 .iter()
661 .map(|value| {
662 match value {
665 LiNo::Ref(_) => format!("{}({})", id_str, value),
666 _ => format!("{}{}", id_str, value),
667 }
668 })
669 .collect::<Vec<_>>()
670 .join("\n");
671 write!(f, "{}", lines)
672 } else {
673 let values_str = values
674 .iter()
675 .map(|value| value.to_string())
676 .collect::<Vec<_>>()
677 .join(" ");
678 write!(f, "({}{})", id_str, values_str)
679 }
680 }
681 }
682 }
683}
684
685impl LiNo<SyntaxReference> {
686 pub fn into_values(self) -> LiNo<String> {
699 match self {
700 LiNo::Ref(reference) => LiNo::Ref(reference.value),
701 LiNo::Link { id, values } => LiNo::Link {
702 id: id.map(|id| id.value),
703 values: values.into_iter().map(LiNo::into_values).collect(),
704 },
705 }
706 }
707
708 pub fn raw_id(&self) -> Option<&str> {
722 match self {
723 LiNo::Ref(reference) => reference.raw.as_deref(),
724 LiNo::Link { id, .. } => id.as_ref().and_then(|id| id.raw.as_deref()),
725 }
726 }
727
728 pub fn quote(&self) -> Option<char> {
731 self.raw_id().and_then(reference_quote)
732 }
733}
734
735impl From<LiNo<SyntaxReference>> for LiNo<String> {
737 fn from(link: LiNo<SyntaxReference>) -> Self {
738 link.into_values()
739 }
740}
741
742impl From<parser::Link> for LiNo<String> {
744 fn from(link: parser::Link) -> Self {
745 if let Some(body) = &link.nested {
746 return transform_nested(body, &plain_id);
747 }
748 if link.values.is_empty() && link.children.is_empty() {
749 if let Some(id) = link.id {
750 LiNo::Ref(id)
751 } else {
752 LiNo::Link {
753 id: None,
754 values: vec![],
755 }
756 }
757 } else {
758 let values: Vec<LiNo<String>> = link.values.into_iter().map(|v| v.into()).collect();
759 LiNo::Link {
760 id: link.id,
761 values,
762 }
763 }
764 }
765}
766
767trait IdReader<T>: Fn(&parser::Link) -> Option<T> {}
770
771impl<T, F: Fn(&parser::Link) -> Option<T>> IdReader<T> for F {}
772
773fn plain_id(link: &parser::Link) -> Option<String> {
775 link.id.clone()
776}
777
778fn syntax_id(link: &parser::Link, document: &str) -> Option<SyntaxReference> {
782 let value = link.id.clone()?;
783 let raw = link
784 .id_span
785 .as_ref()
786 .and_then(|span| document.get(span.clone()))
787 .map(str::to_owned);
788 Some(SyntaxReference { value, raw })
789}
790
791fn transform_nested<T: Clone, F: IdReader<T>>(body: &[parser::Link], id: &F) -> LiNo<T> {
799 let links = flatten_links(body, id);
800 let wraps_single_group =
801 body.len() == 1 && body[0].nested.is_some() && body[0].children.is_empty();
802 if links.len() == 1 && !wraps_single_group {
803 return links.into_iter().next().unwrap();
804 }
805 LiNo::Link {
806 id: None,
807 values: links,
808 }
809}
810
811fn flatten_links<T: Clone, F: IdReader<T>>(links: &[parser::Link], id: &F) -> Vec<LiNo<T>> {
813 let mut result = vec![];
814
815 for link in links {
816 flatten_link_recursive(link, None, &mut result, id);
817 }
818
819 result
820}
821
822fn flatten_link_recursive<T: Clone, F: IdReader<T>>(
823 link: &parser::Link,
824 parent: Option<&LiNo<T>>,
825 result: &mut Vec<LiNo<T>>,
826 id: &F,
827) {
828 if link.is_indented_id
831 && link.id.is_some()
832 && link.values.is_empty()
833 && !link.children.is_empty()
834 {
835 let child_values: Vec<LiNo<T>> = link
836 .children
837 .iter()
838 .map(|child| transform_indented_value(child, id))
839 .collect();
840
841 let current = LiNo::Link {
842 id: id(link),
843 values: child_values,
844 };
845
846 let combined = if let Some(parent) = parent {
847 let wrapped_parent = match parent {
849 LiNo::Ref(ref_id) => LiNo::Link {
850 id: None,
851 values: vec![LiNo::Ref(ref_id.clone())],
852 },
853 link => link.clone(),
854 };
855
856 LiNo::Link {
857 id: None,
858 values: vec![wrapped_parent, current],
859 }
860 } else {
861 current
862 };
863
864 result.push(combined);
865 return; }
867
868 let current = if let Some(body) = &link.nested {
870 transform_nested(body, id)
871 } else if link.values.is_empty() {
872 if let Some(id) = id(link) {
873 LiNo::Ref(id)
874 } else {
875 LiNo::Link {
876 id: None,
877 values: vec![],
878 }
879 }
880 } else {
881 LiNo::Link {
882 id: id(link),
883 values: link
884 .values
885 .iter()
886 .map(|value| transform_value(value, id))
887 .collect(),
888 }
889 };
890
891 let combined = if let Some(parent) = parent {
893 let wrapped_parent = match parent {
895 LiNo::Ref(ref_id) => LiNo::Link {
896 id: None,
897 values: vec![LiNo::Ref(ref_id.clone())],
898 },
899 link => link.clone(),
900 };
901
902 let wrapped_current = match current {
904 LiNo::Ref(ref_id) => LiNo::Link {
905 id: None,
906 values: vec![LiNo::Ref(ref_id)],
907 },
908 link => link,
909 };
910
911 LiNo::Link {
912 id: None,
913 values: vec![wrapped_parent, wrapped_current],
914 }
915 } else {
916 current
917 };
918
919 if link.children.is_empty() {
923 result.push(combined);
924 return;
925 }
926 result.push(combined.clone());
927
928 for child in &link.children {
930 flatten_link_recursive(child, Some(&combined), result, id);
931 }
932}
933
934fn transform_value<T: Clone, F: IdReader<T>>(link: &parser::Link, id: &F) -> LiNo<T> {
936 if let Some(body) = &link.nested {
937 return transform_nested(body, id);
938 }
939 if link.values.is_empty() {
940 return match id(link) {
941 Some(id) => LiNo::Ref(id),
942 None => LiNo::Link {
943 id: None,
944 values: vec![],
945 },
946 };
947 }
948 LiNo::Link {
949 id: id(link),
950 values: link
951 .values
952 .iter()
953 .map(|value| transform_value(value, id))
954 .collect(),
955 }
956}
957
958fn transform_indented_value<T: Clone, F: IdReader<T>>(link: &parser::Link, id: &F) -> LiNo<T> {
960 let children: Vec<_> = link
961 .children
962 .iter()
963 .map(|child| transform_indented_value(child, id))
964 .collect();
965 if !children.is_empty() && link.is_indented_id && link.id.is_some() && link.values.is_empty() {
966 return LiNo::Link {
967 id: id(link),
968 values: children,
969 };
970 }
971 let current = transform_value(link, id);
972
973 if !children.is_empty() {
974 match current {
975 LiNo::Link { id, mut values } => {
976 values.extend(children);
977 LiNo::Link { id, values }
978 }
979 LiNo::Ref(id) => {
980 if link.nested.is_some() {
981 return LiNo::Link {
982 id: Some(id),
983 values: children,
984 };
985 }
986 let mut values = vec![LiNo::Ref(id)];
987 values.extend(children);
988 LiNo::Link { id: None, values }
989 }
990 }
991 } else if link.id.is_none() && link.nested.is_none() && link.values.len() == 1 {
992 match current {
993 LiNo::Link { id: None, values } => values.into_iter().next().unwrap(),
994 value => value,
995 }
996 } else {
997 current
998 }
999}
1000
1001fn prepare<'a>(document: &'a str, config: &ParserConfig) -> Cow<'a, str> {
1007 if config.comments {
1008 Cow::Owned(strip_comments(document))
1009 } else {
1010 Cow::Borrowed(document)
1011 }
1012}
1013
1014pub fn parse_lino(document: &str) -> Result<LiNo<String>, ParseError> {
1033 parse_lino_with_config(document, &ParserConfig::default())
1034}
1035
1036pub fn parse_lino_with_config(
1050 document: &str,
1051 config: &ParserConfig,
1052) -> Result<LiNo<String>, ParseError> {
1053 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1055 return Ok(LiNo::Link {
1056 id: None,
1057 values: vec![],
1058 });
1059 }
1060
1061 let prepared = prepare(document, config);
1062 match parser::parse_prepared_document(&prepared, document, config.max_depth) {
1063 Ok(links) => {
1064 if links.is_empty() {
1065 Ok(LiNo::Link {
1066 id: None,
1067 values: vec![],
1068 })
1069 } else {
1070 let flattened = flatten_links(&links, &plain_id);
1072 Ok(LiNo::Link {
1073 id: None,
1074 values: flattened,
1075 })
1076 }
1077 }
1078 Err(failure) => Err(parse_error(document, failure)),
1079 }
1080}
1081
1082pub fn parse_lino_to_links(document: &str) -> Result<Vec<LiNo<String>>, ParseError> {
1096 parse_lino_to_links_with_config(document, &ParserConfig::default())
1097}
1098
1099pub fn parse_lino_to_links_with_config(
1110 document: &str,
1111 config: &ParserConfig,
1112) -> Result<Vec<LiNo<String>>, ParseError> {
1113 read_links(document, config, &plain_id)
1114}
1115
1116pub fn parse_lino_to_syntax_links(
1150 document: &str,
1151) -> Result<Vec<LiNo<SyntaxReference>>, ParseError> {
1152 parse_lino_to_syntax_links_with_config(document, &ParserConfig::default())
1153}
1154
1155pub fn parse_lino_to_syntax_links_with_config(
1168 document: &str,
1169 config: &ParserConfig,
1170) -> Result<Vec<LiNo<SyntaxReference>>, ParseError> {
1171 read_links(document, config, &|link| syntax_id(link, document))
1172}
1173
1174fn read_links<T: Clone, F: IdReader<T>>(
1177 document: &str,
1178 config: &ParserConfig,
1179 id: &F,
1180) -> Result<Vec<LiNo<T>>, ParseError> {
1181 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1183 return Ok(vec![]);
1184 }
1185
1186 let prepared = prepare(document, config);
1187 match parser::parse_prepared_document(&prepared, document, config.max_depth) {
1188 Ok(links) => {
1189 if links.is_empty() {
1190 Ok(vec![])
1191 } else {
1192 let flattened = flatten_links(&links, id);
1194 Ok(flattened)
1195 }
1196 }
1197 Err(failure) => Err(parse_error(document, failure)),
1198 }
1199}
1200
1201pub(crate) fn check_document<'a>(
1205 document: &'a str,
1206 config: &ParserConfig,
1207) -> Result<Cow<'a, str>, ParseError> {
1208 let prepared = prepare(document, config);
1209 if document.trim_matches(parser::is_whitespace_char).is_empty() {
1210 return Ok(prepared);
1211 }
1212 match parser::parse_prepared_document(&prepared, document, config.max_depth) {
1213 Ok(_) => Ok(prepared),
1214 Err(failure) => Err(parse_error(document, failure)),
1215 }
1216}
1217
1218pub fn format_links(links: &[LiNo<String>]) -> String {
1221 links
1222 .iter()
1223 .map(|link| format!("{}", link))
1224 .collect::<Vec<_>>()
1225 .join("\n")
1226}
1227
1228pub fn format_links_with_config(links: &[LiNo<String>], config: &FormatConfig) -> String {
1238 if links.is_empty() {
1239 return String::new();
1240 }
1241
1242 let links_to_format = if config.group_consecutive {
1244 group_consecutive_links(links)
1245 } else {
1246 links.to_vec()
1247 };
1248
1249 links_to_format
1250 .iter()
1251 .map(|link| link.format_with_config(config))
1252 .collect::<Vec<_>>()
1253 .join("\n")
1254}
1255
1256fn group_consecutive_links(links: &[LiNo<String>]) -> Vec<LiNo<String>> {
1272 if links.is_empty() {
1273 return vec![];
1274 }
1275
1276 let mut grouped = vec![];
1277 let mut i = 0;
1278
1279 while i < links.len() {
1280 let current = &links[i];
1281
1282 if let LiNo::Link {
1284 id: Some(current_id),
1285 values: current_values,
1286 } = current
1287 {
1288 if !current_values.is_empty() {
1289 let mut same_id_values = current_values.clone();
1291 let mut j = i + 1;
1292
1293 while j < links.len() {
1294 if let LiNo::Link {
1295 id: Some(next_id),
1296 values: next_values,
1297 } = &links[j]
1298 {
1299 if next_id == current_id && !next_values.is_empty() {
1300 same_id_values.extend(next_values.clone());
1301 j += 1;
1302 } else {
1303 break;
1304 }
1305 } else {
1306 break;
1307 }
1308 }
1309
1310 if j > i + 1 {
1312 grouped.push(LiNo::Link {
1313 id: Some(current_id.clone()),
1314 values: same_id_values,
1315 });
1316 i = j;
1317 continue;
1318 }
1319 }
1320 }
1321
1322 grouped.push(current.clone());
1323 i += 1;
1324 }
1325
1326 grouped
1327}
1328
1329fn escape_reference(reference: &str) -> String {
1331 reference_literal::format_reference(reference)
1332}
1333
1334fn has_lone_nested_value<T>(values: &[LiNo<T>]) -> bool {
1338 matches!(values, [LiNo::Link { values: nested, .. }] if !nested.is_empty())
1339}
1340
1341fn needs_parentheses(s: &str) -> bool {
1343 s.contains(' ') || s.contains(':') || s.contains('(') || s.contains(')')
1344}
1345
1346fn format_value<T: ToString>(value: &LiNo<T>) -> String {
1348 match value {
1349 LiNo::Ref(r) => escape_reference(&r.to_string()),
1350 LiNo::Link { id, values } => {
1351 if values.is_empty() {
1353 if let Some(id_val) = id {
1354 return escape_reference(&id_val.to_string());
1355 }
1356 return String::new();
1357 }
1358 format!("{}", value)
1360 }
1361 }
1362}
1363
1364macro_rules! impl_tuple_from {
1401 (@str_tuple 2, $t0:tt, $t1:tt) => {
1403 impl From<(&str, &str)> for LiNo<String> {
1404 fn from(tuple: (&str, &str)) -> Self {
1405 LiNo::Link {
1406 id: Some(tuple.$t0.to_string()),
1407 values: vec![LiNo::Ref(tuple.$t1.to_string())],
1408 }
1409 }
1410 }
1411 };
1412 (@string_tuple 2, $t0:tt, $t1:tt) => {
1413 impl From<(String, String)> for LiNo<String> {
1414 fn from(tuple: (String, String)) -> Self {
1415 LiNo::Link {
1416 id: Some(tuple.$t0),
1417 values: vec![LiNo::Ref(tuple.$t1)],
1418 }
1419 }
1420 }
1421 };
1422 (@str_lino_tuple 2, $t0:tt, $t1:tt) => {
1423 impl From<(&str, LiNo<String>)> for LiNo<String> {
1424 fn from(tuple: (&str, LiNo<String>)) -> Self {
1425 LiNo::Link {
1426 id: Some(tuple.$t0.to_string()),
1427 values: vec![tuple.$t1],
1428 }
1429 }
1430 }
1431 };
1432 (@lino_tuple 2, $t0:tt, $t1:tt) => {
1433 impl From<(LiNo<String>, LiNo<String>)> for LiNo<String> {
1434 fn from(tuple: (LiNo<String>, LiNo<String>)) -> Self {
1435 LiNo::Link {
1436 id: None,
1437 values: vec![tuple.$t0, tuple.$t1],
1438 }
1439 }
1440 }
1441 };
1442
1443 (@str_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1445 impl From<(&str, &str, &str)> for LiNo<String> {
1446 fn from(tuple: (&str, &str, &str)) -> Self {
1447 LiNo::Link {
1448 id: Some(tuple.$t0.to_string()),
1449 values: vec![LiNo::Ref(tuple.$t1.to_string()), LiNo::Ref(tuple.$t2.to_string())],
1450 }
1451 }
1452 }
1453 };
1454 (@string_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1455 impl From<(String, String, String)> for LiNo<String> {
1456 fn from(tuple: (String, String, String)) -> Self {
1457 LiNo::Link {
1458 id: Some(tuple.$t0),
1459 values: vec![LiNo::Ref(tuple.$t1), LiNo::Ref(tuple.$t2)],
1460 }
1461 }
1462 }
1463 };
1464 (@str_lino_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1465 impl From<(&str, LiNo<String>, LiNo<String>)> for LiNo<String> {
1466 fn from(tuple: (&str, LiNo<String>, LiNo<String>)) -> Self {
1467 LiNo::Link {
1468 id: Some(tuple.$t0.to_string()),
1469 values: vec![tuple.$t1, tuple.$t2],
1470 }
1471 }
1472 }
1473 };
1474 (@lino_tuple 3, $t0:tt, $t1:tt, $t2:tt) => {
1475 impl From<(LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1476 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1477 LiNo::Link {
1478 id: None,
1479 values: vec![tuple.$t0, tuple.$t1, tuple.$t2],
1480 }
1481 }
1482 }
1483 };
1484
1485 (@str_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1487 impl From<(&str, &str, &str, &str)> for LiNo<String> {
1488 fn from(tuple: (&str, &str, &str, &str)) -> Self {
1489 LiNo::Link {
1490 id: Some(tuple.$t0.to_string()),
1491 values: vec![
1492 LiNo::Ref(tuple.$t1.to_string()),
1493 LiNo::Ref(tuple.$t2.to_string()),
1494 LiNo::Ref(tuple.$t3.to_string()),
1495 ],
1496 }
1497 }
1498 }
1499 };
1500 (@string_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1501 impl From<(String, String, String, String)> for LiNo<String> {
1502 fn from(tuple: (String, String, String, String)) -> Self {
1503 LiNo::Link {
1504 id: Some(tuple.$t0),
1505 values: vec![LiNo::Ref(tuple.$t1), LiNo::Ref(tuple.$t2), LiNo::Ref(tuple.$t3)],
1506 }
1507 }
1508 }
1509 };
1510 (@str_lino_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1511 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1512 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1513 LiNo::Link {
1514 id: Some(tuple.$t0.to_string()),
1515 values: vec![tuple.$t1, tuple.$t2, tuple.$t3],
1516 }
1517 }
1518 }
1519 };
1520 (@lino_tuple 4, $t0:tt, $t1:tt, $t2:tt, $t3:tt) => {
1521 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1522 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1523 LiNo::Link {
1524 id: None,
1525 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3],
1526 }
1527 }
1528 }
1529 };
1530
1531 (@str_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1533 impl From<(&str, &str, &str, &str, &str)> for LiNo<String> {
1534 fn from(tuple: (&str, &str, &str, &str, &str)) -> Self {
1535 LiNo::Link {
1536 id: Some(tuple.$t0.to_string()),
1537 values: vec![
1538 LiNo::Ref(tuple.$t1.to_string()),
1539 LiNo::Ref(tuple.$t2.to_string()),
1540 LiNo::Ref(tuple.$t3.to_string()),
1541 LiNo::Ref(tuple.$t4.to_string()),
1542 ],
1543 }
1544 }
1545 }
1546 };
1547 (@string_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1548 impl From<(String, String, String, String, String)> for LiNo<String> {
1549 fn from(tuple: (String, String, String, String, String)) -> Self {
1550 LiNo::Link {
1551 id: Some(tuple.$t0),
1552 values: vec![
1553 LiNo::Ref(tuple.$t1),
1554 LiNo::Ref(tuple.$t2),
1555 LiNo::Ref(tuple.$t3),
1556 LiNo::Ref(tuple.$t4),
1557 ],
1558 }
1559 }
1560 }
1561 };
1562 (@str_lino_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1563 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1564 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1565 LiNo::Link {
1566 id: Some(tuple.$t0.to_string()),
1567 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4],
1568 }
1569 }
1570 }
1571 };
1572 (@lino_tuple 5, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt) => {
1573 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1574 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1575 LiNo::Link {
1576 id: None,
1577 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4],
1578 }
1579 }
1580 }
1581 };
1582
1583 (@str_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1585 impl From<(&str, &str, &str, &str, &str, &str)> for LiNo<String> {
1586 fn from(tuple: (&str, &str, &str, &str, &str, &str)) -> Self {
1587 LiNo::Link {
1588 id: Some(tuple.$t0.to_string()),
1589 values: vec![
1590 LiNo::Ref(tuple.$t1.to_string()),
1591 LiNo::Ref(tuple.$t2.to_string()),
1592 LiNo::Ref(tuple.$t3.to_string()),
1593 LiNo::Ref(tuple.$t4.to_string()),
1594 LiNo::Ref(tuple.$t5.to_string()),
1595 ],
1596 }
1597 }
1598 }
1599 };
1600 (@string_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1601 impl From<(String, String, String, String, String, String)> for LiNo<String> {
1602 fn from(tuple: (String, String, String, String, String, String)) -> Self {
1603 LiNo::Link {
1604 id: Some(tuple.$t0),
1605 values: vec![
1606 LiNo::Ref(tuple.$t1),
1607 LiNo::Ref(tuple.$t2),
1608 LiNo::Ref(tuple.$t3),
1609 LiNo::Ref(tuple.$t4),
1610 LiNo::Ref(tuple.$t5),
1611 ],
1612 }
1613 }
1614 }
1615 };
1616 (@str_lino_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1617 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1618 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1619 LiNo::Link {
1620 id: Some(tuple.$t0.to_string()),
1621 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5],
1622 }
1623 }
1624 }
1625 };
1626 (@lino_tuple 6, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt) => {
1627 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1628 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1629 LiNo::Link {
1630 id: None,
1631 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5],
1632 }
1633 }
1634 }
1635 };
1636
1637 (@str_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1639 impl From<(&str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1640 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str)) -> Self {
1641 LiNo::Link {
1642 id: Some(tuple.$t0.to_string()),
1643 values: vec![
1644 LiNo::Ref(tuple.$t1.to_string()),
1645 LiNo::Ref(tuple.$t2.to_string()),
1646 LiNo::Ref(tuple.$t3.to_string()),
1647 LiNo::Ref(tuple.$t4.to_string()),
1648 LiNo::Ref(tuple.$t5.to_string()),
1649 LiNo::Ref(tuple.$t6.to_string()),
1650 ],
1651 }
1652 }
1653 }
1654 };
1655 (@string_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1656 impl From<(String, String, String, String, String, String, String)> for LiNo<String> {
1657 fn from(tuple: (String, String, String, String, String, String, String)) -> Self {
1658 LiNo::Link {
1659 id: Some(tuple.$t0),
1660 values: vec![
1661 LiNo::Ref(tuple.$t1),
1662 LiNo::Ref(tuple.$t2),
1663 LiNo::Ref(tuple.$t3),
1664 LiNo::Ref(tuple.$t4),
1665 LiNo::Ref(tuple.$t5),
1666 LiNo::Ref(tuple.$t6),
1667 ],
1668 }
1669 }
1670 }
1671 };
1672 (@str_lino_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1673 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1674 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1675 LiNo::Link {
1676 id: Some(tuple.$t0.to_string()),
1677 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6],
1678 }
1679 }
1680 }
1681 };
1682 (@lino_tuple 7, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt) => {
1683 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1684 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1685 LiNo::Link {
1686 id: None,
1687 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6],
1688 }
1689 }
1690 }
1691 };
1692
1693 (@str_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1695 impl From<(&str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1696 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1697 LiNo::Link {
1698 id: Some(tuple.$t0.to_string()),
1699 values: vec![
1700 LiNo::Ref(tuple.$t1.to_string()),
1701 LiNo::Ref(tuple.$t2.to_string()),
1702 LiNo::Ref(tuple.$t3.to_string()),
1703 LiNo::Ref(tuple.$t4.to_string()),
1704 LiNo::Ref(tuple.$t5.to_string()),
1705 LiNo::Ref(tuple.$t6.to_string()),
1706 LiNo::Ref(tuple.$t7.to_string()),
1707 ],
1708 }
1709 }
1710 }
1711 };
1712 (@string_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1713 impl From<(String, String, String, String, String, String, String, String)> for LiNo<String> {
1714 fn from(tuple: (String, String, String, String, String, String, String, String)) -> Self {
1715 LiNo::Link {
1716 id: Some(tuple.$t0),
1717 values: vec![
1718 LiNo::Ref(tuple.$t1),
1719 LiNo::Ref(tuple.$t2),
1720 LiNo::Ref(tuple.$t3),
1721 LiNo::Ref(tuple.$t4),
1722 LiNo::Ref(tuple.$t5),
1723 LiNo::Ref(tuple.$t6),
1724 LiNo::Ref(tuple.$t7),
1725 ],
1726 }
1727 }
1728 }
1729 };
1730 (@str_lino_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1731 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1732 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1733 LiNo::Link {
1734 id: Some(tuple.$t0.to_string()),
1735 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7],
1736 }
1737 }
1738 }
1739 };
1740 (@lino_tuple 8, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt) => {
1741 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1742 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1743 LiNo::Link {
1744 id: None,
1745 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7],
1746 }
1747 }
1748 }
1749 };
1750
1751 (@str_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1753 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1754 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1755 LiNo::Link {
1756 id: Some(tuple.$t0.to_string()),
1757 values: vec![
1758 LiNo::Ref(tuple.$t1.to_string()),
1759 LiNo::Ref(tuple.$t2.to_string()),
1760 LiNo::Ref(tuple.$t3.to_string()),
1761 LiNo::Ref(tuple.$t4.to_string()),
1762 LiNo::Ref(tuple.$t5.to_string()),
1763 LiNo::Ref(tuple.$t6.to_string()),
1764 LiNo::Ref(tuple.$t7.to_string()),
1765 LiNo::Ref(tuple.$t8.to_string()),
1766 ],
1767 }
1768 }
1769 }
1770 };
1771 (@string_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1772 impl From<(String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1773 fn from(tuple: (String, String, String, String, String, String, String, String, String)) -> Self {
1774 LiNo::Link {
1775 id: Some(tuple.$t0),
1776 values: vec![
1777 LiNo::Ref(tuple.$t1),
1778 LiNo::Ref(tuple.$t2),
1779 LiNo::Ref(tuple.$t3),
1780 LiNo::Ref(tuple.$t4),
1781 LiNo::Ref(tuple.$t5),
1782 LiNo::Ref(tuple.$t6),
1783 LiNo::Ref(tuple.$t7),
1784 LiNo::Ref(tuple.$t8),
1785 ],
1786 }
1787 }
1788 }
1789 };
1790 (@str_lino_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1791 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1792 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1793 LiNo::Link {
1794 id: Some(tuple.$t0.to_string()),
1795 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8],
1796 }
1797 }
1798 }
1799 };
1800 (@lino_tuple 9, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt) => {
1801 impl From<(LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1802 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1803 LiNo::Link {
1804 id: None,
1805 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8],
1806 }
1807 }
1808 }
1809 };
1810
1811 (@str_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1813 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1814 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1815 LiNo::Link {
1816 id: Some(tuple.$t0.to_string()),
1817 values: vec![
1818 LiNo::Ref(tuple.$t1.to_string()),
1819 LiNo::Ref(tuple.$t2.to_string()),
1820 LiNo::Ref(tuple.$t3.to_string()),
1821 LiNo::Ref(tuple.$t4.to_string()),
1822 LiNo::Ref(tuple.$t5.to_string()),
1823 LiNo::Ref(tuple.$t6.to_string()),
1824 LiNo::Ref(tuple.$t7.to_string()),
1825 LiNo::Ref(tuple.$t8.to_string()),
1826 LiNo::Ref(tuple.$t9.to_string()),
1827 ],
1828 }
1829 }
1830 }
1831 };
1832 (@string_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1833 impl From<(String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1834 fn from(tuple: (String, String, String, String, String, String, String, String, String, String)) -> Self {
1835 LiNo::Link {
1836 id: Some(tuple.$t0),
1837 values: vec![
1838 LiNo::Ref(tuple.$t1),
1839 LiNo::Ref(tuple.$t2),
1840 LiNo::Ref(tuple.$t3),
1841 LiNo::Ref(tuple.$t4),
1842 LiNo::Ref(tuple.$t5),
1843 LiNo::Ref(tuple.$t6),
1844 LiNo::Ref(tuple.$t7),
1845 LiNo::Ref(tuple.$t8),
1846 LiNo::Ref(tuple.$t9),
1847 ],
1848 }
1849 }
1850 }
1851 };
1852 (@str_lino_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1853 impl From<(&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)> for LiNo<String> {
1854 fn from(tuple: (&str, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1855 LiNo::Link {
1856 id: Some(tuple.$t0.to_string()),
1857 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9],
1858 }
1859 }
1860 }
1861 };
1862 (@lino_tuple 10, $t0:tt, $t1:tt, $t2:tt, $t3:tt, $t4:tt, $t5:tt, $t6:tt, $t7:tt, $t8:tt, $t9:tt) => {
1863 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> {
1864 fn from(tuple: (LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>, LiNo<String>)) -> Self {
1865 LiNo::Link {
1866 id: None,
1867 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9],
1868 }
1869 }
1870 }
1871 };
1872
1873 (@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) => {
1875 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1876 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1877 LiNo::Link {
1878 id: Some(tuple.$t0.to_string()),
1879 values: vec![
1880 LiNo::Ref(tuple.$t1.to_string()),
1881 LiNo::Ref(tuple.$t2.to_string()),
1882 LiNo::Ref(tuple.$t3.to_string()),
1883 LiNo::Ref(tuple.$t4.to_string()),
1884 LiNo::Ref(tuple.$t5.to_string()),
1885 LiNo::Ref(tuple.$t6.to_string()),
1886 LiNo::Ref(tuple.$t7.to_string()),
1887 LiNo::Ref(tuple.$t8.to_string()),
1888 LiNo::Ref(tuple.$t9.to_string()),
1889 LiNo::Ref(tuple.$t10.to_string()),
1890 ],
1891 }
1892 }
1893 }
1894 };
1895 (@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) => {
1896 impl From<(String, String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1897 fn from(tuple: (String, String, String, String, String, String, String, String, String, String, String)) -> Self {
1898 LiNo::Link {
1899 id: Some(tuple.$t0),
1900 values: vec![
1901 LiNo::Ref(tuple.$t1),
1902 LiNo::Ref(tuple.$t2),
1903 LiNo::Ref(tuple.$t3),
1904 LiNo::Ref(tuple.$t4),
1905 LiNo::Ref(tuple.$t5),
1906 LiNo::Ref(tuple.$t6),
1907 LiNo::Ref(tuple.$t7),
1908 LiNo::Ref(tuple.$t8),
1909 LiNo::Ref(tuple.$t9),
1910 LiNo::Ref(tuple.$t10),
1911 ],
1912 }
1913 }
1914 }
1915 };
1916 (@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) => {
1917 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> {
1918 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 {
1919 LiNo::Link {
1920 id: Some(tuple.$t0.to_string()),
1921 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10],
1922 }
1923 }
1924 }
1925 };
1926 (@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) => {
1927 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> {
1928 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 {
1929 LiNo::Link {
1930 id: None,
1931 values: vec![tuple.$t0, tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10],
1932 }
1933 }
1934 }
1935 };
1936
1937 (@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) => {
1939 impl From<(&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)> for LiNo<String> {
1940 fn from(tuple: (&str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
1941 LiNo::Link {
1942 id: Some(tuple.$t0.to_string()),
1943 values: vec![
1944 LiNo::Ref(tuple.$t1.to_string()),
1945 LiNo::Ref(tuple.$t2.to_string()),
1946 LiNo::Ref(tuple.$t3.to_string()),
1947 LiNo::Ref(tuple.$t4.to_string()),
1948 LiNo::Ref(tuple.$t5.to_string()),
1949 LiNo::Ref(tuple.$t6.to_string()),
1950 LiNo::Ref(tuple.$t7.to_string()),
1951 LiNo::Ref(tuple.$t8.to_string()),
1952 LiNo::Ref(tuple.$t9.to_string()),
1953 LiNo::Ref(tuple.$t10.to_string()),
1954 LiNo::Ref(tuple.$t11.to_string()),
1955 ],
1956 }
1957 }
1958 }
1959 };
1960 (@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) => {
1961 impl From<(String, String, String, String, String, String, String, String, String, String, String, String)> for LiNo<String> {
1962 fn from(tuple: (String, String, String, String, String, String, String, String, String, String, String, String)) -> Self {
1963 LiNo::Link {
1964 id: Some(tuple.$t0),
1965 values: vec![
1966 LiNo::Ref(tuple.$t1),
1967 LiNo::Ref(tuple.$t2),
1968 LiNo::Ref(tuple.$t3),
1969 LiNo::Ref(tuple.$t4),
1970 LiNo::Ref(tuple.$t5),
1971 LiNo::Ref(tuple.$t6),
1972 LiNo::Ref(tuple.$t7),
1973 LiNo::Ref(tuple.$t8),
1974 LiNo::Ref(tuple.$t9),
1975 LiNo::Ref(tuple.$t10),
1976 LiNo::Ref(tuple.$t11),
1977 ],
1978 }
1979 }
1980 }
1981 };
1982 (@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) => {
1983 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> {
1984 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 {
1985 LiNo::Link {
1986 id: Some(tuple.$t0.to_string()),
1987 values: vec![tuple.$t1, tuple.$t2, tuple.$t3, tuple.$t4, tuple.$t5, tuple.$t6, tuple.$t7, tuple.$t8, tuple.$t9, tuple.$t10, tuple.$t11],
1988 }
1989 }
1990 }
1991 };
1992 (@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) => {
1993 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> {
1994 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 {
1995 LiNo::Link {
1996 id: None,
1997 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],
1998 }
1999 }
2000 }
2001 };
2002
2003 (2) => {
2005 impl_tuple_from!(@str_tuple 2, 0, 1);
2006 impl_tuple_from!(@string_tuple 2, 0, 1);
2007 impl_tuple_from!(@str_lino_tuple 2, 0, 1);
2008 impl_tuple_from!(@lino_tuple 2, 0, 1);
2009 };
2010 (3) => {
2011 impl_tuple_from!(@str_tuple 3, 0, 1, 2);
2012 impl_tuple_from!(@string_tuple 3, 0, 1, 2);
2013 impl_tuple_from!(@str_lino_tuple 3, 0, 1, 2);
2014 impl_tuple_from!(@lino_tuple 3, 0, 1, 2);
2015 };
2016 (4) => {
2017 impl_tuple_from!(@str_tuple 4, 0, 1, 2, 3);
2018 impl_tuple_from!(@string_tuple 4, 0, 1, 2, 3);
2019 impl_tuple_from!(@str_lino_tuple 4, 0, 1, 2, 3);
2020 impl_tuple_from!(@lino_tuple 4, 0, 1, 2, 3);
2021 };
2022 (5) => {
2023 impl_tuple_from!(@str_tuple 5, 0, 1, 2, 3, 4);
2024 impl_tuple_from!(@string_tuple 5, 0, 1, 2, 3, 4);
2025 impl_tuple_from!(@str_lino_tuple 5, 0, 1, 2, 3, 4);
2026 impl_tuple_from!(@lino_tuple 5, 0, 1, 2, 3, 4);
2027 };
2028 (6) => {
2029 impl_tuple_from!(@str_tuple 6, 0, 1, 2, 3, 4, 5);
2030 impl_tuple_from!(@string_tuple 6, 0, 1, 2, 3, 4, 5);
2031 impl_tuple_from!(@str_lino_tuple 6, 0, 1, 2, 3, 4, 5);
2032 impl_tuple_from!(@lino_tuple 6, 0, 1, 2, 3, 4, 5);
2033 };
2034 (7) => {
2035 impl_tuple_from!(@str_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2036 impl_tuple_from!(@string_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2037 impl_tuple_from!(@str_lino_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2038 impl_tuple_from!(@lino_tuple 7, 0, 1, 2, 3, 4, 5, 6);
2039 };
2040 (8) => {
2041 impl_tuple_from!(@str_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2042 impl_tuple_from!(@string_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2043 impl_tuple_from!(@str_lino_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2044 impl_tuple_from!(@lino_tuple 8, 0, 1, 2, 3, 4, 5, 6, 7);
2045 };
2046 (9) => {
2047 impl_tuple_from!(@str_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2048 impl_tuple_from!(@string_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2049 impl_tuple_from!(@str_lino_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2050 impl_tuple_from!(@lino_tuple 9, 0, 1, 2, 3, 4, 5, 6, 7, 8);
2051 };
2052 (10) => {
2053 impl_tuple_from!(@str_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2054 impl_tuple_from!(@string_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2055 impl_tuple_from!(@str_lino_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2056 impl_tuple_from!(@lino_tuple 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2057 };
2058 (11) => {
2059 impl_tuple_from!(@str_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2060 impl_tuple_from!(@string_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2061 impl_tuple_from!(@str_lino_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2062 impl_tuple_from!(@lino_tuple 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2063 };
2064 (12) => {
2065 impl_tuple_from!(@str_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2066 impl_tuple_from!(@string_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2067 impl_tuple_from!(@str_lino_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2068 impl_tuple_from!(@lino_tuple 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
2069 };
2070}
2071
2072impl_tuple_from!(2);
2075impl_tuple_from!(3);
2076impl_tuple_from!(4);
2077impl_tuple_from!(5);
2078impl_tuple_from!(6);
2079impl_tuple_from!(7);
2080impl_tuple_from!(8);
2081impl_tuple_from!(9);
2082impl_tuple_from!(10);
2083impl_tuple_from!(11);
2084impl_tuple_from!(12);
2085
2086impl From<Vec<&str>> for LiNo<String> {
2117 fn from(values: Vec<&str>) -> Self {
2118 LiNo::Link {
2119 id: None,
2120 values: values
2121 .into_iter()
2122 .map(|s| LiNo::Ref(s.to_string()))
2123 .collect(),
2124 }
2125 }
2126}
2127
2128impl From<Vec<String>> for LiNo<String> {
2130 fn from(values: Vec<String>) -> Self {
2131 LiNo::Link {
2132 id: None,
2133 values: values.into_iter().map(LiNo::Ref).collect(),
2134 }
2135 }
2136}
2137
2138impl From<Vec<LiNo<String>>> for LiNo<String> {
2140 fn from(values: Vec<LiNo<String>>) -> Self {
2141 LiNo::Link { id: None, values }
2142 }
2143}
2144
2145impl From<(&str, Vec<&str>)> for LiNo<String> {
2157 fn from((id, values): (&str, Vec<&str>)) -> Self {
2158 LiNo::Link {
2159 id: Some(id.to_string()),
2160 values: values
2161 .into_iter()
2162 .map(|s| LiNo::Ref(s.to_string()))
2163 .collect(),
2164 }
2165 }
2166}
2167
2168impl From<(String, Vec<String>)> for LiNo<String> {
2170 fn from((id, values): (String, Vec<String>)) -> Self {
2171 LiNo::Link {
2172 id: Some(id),
2173 values: values.into_iter().map(LiNo::Ref).collect(),
2174 }
2175 }
2176}
2177
2178impl From<(&str, Vec<LiNo<String>>)> for LiNo<String> {
2180 fn from((id, values): (&str, Vec<LiNo<String>>)) -> Self {
2181 LiNo::Link {
2182 id: Some(id.to_string()),
2183 values,
2184 }
2185 }
2186}
2187
2188impl From<(String, Vec<LiNo<String>>)> for LiNo<String> {
2190 fn from((id, values): (String, Vec<LiNo<String>>)) -> Self {
2191 LiNo::Link {
2192 id: Some(id),
2193 values,
2194 }
2195 }
2196}