libgir/writer/
primitives.rs
1use super::defines::*;
2
3pub fn tabs(num: usize) -> String {
6 format!("{:1$}", "", TAB_SIZE * num)
7}
8
9pub fn format_block(prefix: &str, suffix: &str, body: &[String]) -> Vec<String> {
10 let mut v = Vec::new();
11 if !prefix.is_empty() {
12 v.push(prefix.into());
13 }
14 for s in body.iter() {
15 let s = format!("{TAB}{s}");
16 v.push(s);
17 }
18 if !suffix.is_empty() {
19 v.push(suffix.into());
20 }
21 v
22}
23
24pub fn format_block_one_line(
25 prefix: &str,
26 suffix: &str,
27 body: &[String],
28 outer_separator: &str,
29 inner_separator: &str,
30) -> String {
31 let mut s = format!("{prefix}{outer_separator}");
32 let mut first = true;
33 for s_ in body {
34 if first {
35 first = false;
36 s = s + s_;
37 } else {
38 s = s + inner_separator + s_;
39 }
40 }
41 s + outer_separator + suffix
42}
43
44pub fn format_block_smart(
45 prefix: &str,
46 suffix: &str,
47 body: &[String],
48 outer_separator: &str,
49 inner_separator: &str,
50) -> Vec<String> {
51 format_block_smart_width(
52 prefix,
53 suffix,
54 body,
55 outer_separator,
56 inner_separator,
57 MAX_TEXT_WIDTH,
58 )
59}
60
61pub fn format_block_smart_width(
62 prefix: &str,
63 suffix: &str,
64 body: &[String],
65 outer_separator: &str,
66 inner_separator: &str,
67 max_width: usize,
68) -> Vec<String> {
69 let outer_len = prefix.len() + suffix.len() + 2 * outer_separator.len();
70 let mut inner_len = inner_separator.len() * (body.len() - 1);
71 for s in body {
73 inner_len += s.len();
74 }
75 if (outer_len + inner_len) > max_width {
76 format_block(prefix, suffix, body)
77 } else {
78 let s = format_block_one_line(prefix, suffix, body, outer_separator, inner_separator);
79 vec![s]
80 }
81}
82
83pub fn comment_block(body: &[String]) -> Vec<String> {
84 body.iter().map(|s| format!("//{s}")).collect()
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_tabs() {
93 assert_eq!(tabs(0), "");
94 assert_eq!(tabs(1), TAB);
95 assert_eq!(tabs(2), format!("{TAB}{TAB}"));
96 }
97
98 #[test]
99 fn test_format_block() {
100 let body = vec!["0 => 1,".into(), "1 => 0,".into()];
101 let actual = format_block("match a {", "}", &body);
102 let expected = ["match a {", " 0 => 1,", " 1 => 0,", "}"];
103 assert_eq!(actual, expected);
104 }
105
106 #[test]
107 fn test_format_block_smart_width_one_line_outer_separator() {
108 let body = vec!["f()".into()];
109 let actual = format_block_smart_width("unsafe {", "}", &body, " ", "", 14);
110 let expected = ["unsafe { f() }"];
111 assert_eq!(actual, expected);
112 }
113
114 #[test]
115 fn test_format_block_smart_width_many_lines_outer_separator() {
116 let body = vec!["f()".into()];
117 let actual = format_block_smart_width("unsafe {", "}", &body, " ", "", 13);
118 let expected = ["unsafe {", " f()", "}"];
119 assert_eq!(actual, expected);
120 }
121
122 #[test]
123 fn test_format_block_smart_one_line_inner_separator() {
124 let body = vec!["a: &str".into(), "b: &str".into()];
125 let actual = format_block_smart("f(", ")", &body, "", ", ");
126 let expected = ["f(a: &str, b: &str)"];
127 assert_eq!(actual, expected);
128 }
129
130 #[test]
131 fn test_comment_block() {
132 let body = vec!["f(a,".into(), " b)".into()];
133 let actual = comment_block(&body);
134 let expected = ["//f(a,", "// b)"];
135 assert_eq!(actual, expected);
136 }
137}