hocon_rs/raw/
raw_string.rs1use derive_more::{Constructor, Deref, DerefMut};
2use std::fmt::{Debug, Display, Formatter};
3
4use crate::{
5 join, join_debug,
6 path::{Key, Path},
7 raw::raw_value::{
8 RAW_CONCAT_STRING_TYPE, RAW_MULTILINE_STRING_TYPE, RAW_QUOTED_STRING_TYPE,
9 RAW_UNQUOTED_STRING_TYPE,
10 },
11};
12
13#[derive(Clone, Eq, PartialEq, Hash)]
18pub enum RawString {
19 QuotedString(String),
21 UnquotedString(String),
23 MultilineString(String),
25 PathExpression(PathExpression),
27}
28
29#[derive(Clone, Eq, PartialEq, Hash, Constructor, Deref, DerefMut)]
30pub struct PathExpression(Vec<RawString>);
31
32impl PathExpression {
33 pub fn into_inner(self) -> Vec<RawString> {
34 self.0
35 }
36}
37
38impl Debug for PathExpression {
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 join_debug(self.iter(), ".", f)
41 }
42}
43
44impl Display for PathExpression {
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 join(self.iter(), ".", f)
47 }
48}
49
50impl From<&str> for RawString {
51 fn from(val: &str) -> Self {
52 if val.chars().any(|c| c == '\n') {
53 RawString::multiline(val)
54 } else {
55 RawString::quoted(val)
56 }
57 }
58}
59
60impl From<String> for RawString {
61 fn from(val: String) -> Self {
62 if val.chars().any(|c| c == '\n') {
63 RawString::multiline(val)
64 } else {
65 RawString::quoted(val)
66 }
67 }
68}
69
70impl RawString {
71 pub fn ty(&self) -> &'static str {
72 match self {
73 RawString::QuotedString(_) => RAW_QUOTED_STRING_TYPE,
74 RawString::UnquotedString(_) => RAW_UNQUOTED_STRING_TYPE,
75 RawString::MultilineString(_) => RAW_MULTILINE_STRING_TYPE,
76 RawString::PathExpression(_) => RAW_CONCAT_STRING_TYPE,
77 }
78 }
79
80 pub fn as_path(&self) -> Vec<&str> {
81 match self {
82 RawString::QuotedString(s)
83 | RawString::UnquotedString(s)
84 | RawString::MultilineString(s) => vec![s],
85 RawString::PathExpression(c) => c.iter().flat_map(|s| s.as_path()).collect(),
86 }
87 }
88
89 pub fn into_path(self) -> Path {
90 match self {
91 RawString::QuotedString(s)
92 | RawString::UnquotedString(s)
93 | RawString::MultilineString(s) => Path::new(Key::String(s), None),
94 RawString::PathExpression(c) => {
95 let mut dummy = Path::new(Key::String("".to_string()), None);
96 let mut curr = &mut dummy;
97 for path in c.into_inner() {
98 curr.remainder = Some(Box::new(path.into_path()));
99 curr = curr.remainder.as_mut().unwrap();
100 }
101 *dummy.remainder.expect("empty path found")
102 }
103 }
104 }
105
106 pub fn quoted(string: impl Into<String>) -> Self {
107 Self::QuotedString(string.into())
108 }
109
110 pub fn unquoted(string: impl Into<String>) -> Self {
111 Self::UnquotedString(string.into())
112 }
113
114 pub fn multiline(string: impl Into<String>) -> Self {
115 Self::MultilineString(string.into())
116 }
117
118 pub fn path_expression(paths: Vec<RawString>) -> Self {
119 Self::PathExpression(PathExpression::new(paths))
120 }
121}
122
123impl Display for RawString {
124 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
125 match self {
126 RawString::QuotedString(s) => write!(f, "{}", s),
127 RawString::UnquotedString(s) => write!(f, "{}", s),
128 RawString::MultilineString(s) => write!(f, "{}", s),
129 RawString::PathExpression(s) => write!(f, "{}", s),
130 }
131 }
132}
133
134impl Debug for RawString {
135 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
136 match self {
137 Self::QuotedString(s) => {
138 write!(f, "\"{:?}\"", s)
139 }
140 Self::UnquotedString(s) => {
141 write!(f, "{:?}", s)
142 }
143 Self::MultilineString(s) => {
144 write!(f, "\"\"\"{:?}\"\"\"", s)
145 }
146 Self::PathExpression(s) => {
147 write!(f, "{:?}", s)
148 }
149 }
150 }
151}