1use crate::parser::{Error, Parser};
35use plugx_input::Input;
36use std::fmt::{Display, Formatter};
37use url::Url;
38
39#[derive(Debug, Clone, PartialEq)]
41pub struct ConfigurationEntity {
42 item: String,
43 loader_name: String,
44 url: Url,
45 plugin_name: String,
46 maybe_format: Option<String>,
47 maybe_contents: Option<String>,
48 maybe_parsed: Option<Input>,
49}
50
51impl ConfigurationEntity {
52 pub fn new<I, P, L>(item: I, url: Url, plugin_name: P, loader_name: L) -> Self
59 where
60 I: AsRef<str>,
61 P: AsRef<str>,
62 L: AsRef<str>,
63 {
64 Self {
65 url,
66 item: item.as_ref().to_string(),
67 plugin_name: plugin_name.as_ref().to_string(),
68 loader_name: loader_name.as_ref().to_string(),
69 maybe_format: Default::default(),
70 maybe_contents: Default::default(),
71 maybe_parsed: Default::default(),
72 }
73 }
74
75 pub fn set_format<F: AsRef<str>>(&mut self, format: F) {
76 self.maybe_format = Some(format.as_ref().to_string());
77 }
78
79 pub fn with_format<F: AsRef<str>>(mut self, format: F) -> Self {
80 self.set_format(format);
81 self
82 }
83
84 pub fn set_contents<C: AsRef<str>>(&mut self, contents: C) {
85 self.maybe_contents = Some(contents.as_ref().to_string());
86 }
87
88 pub fn with_contents<C: AsRef<str>>(mut self, contents: C) -> Self {
89 self.set_contents(contents);
90 self
91 }
92
93 pub fn set_parsed_contents<I: Into<Input>>(&mut self, contents: I) {
94 self.maybe_parsed = Some(contents.into());
95 }
96
97 pub fn with_parsed_contents<I: Into<Input>>(mut self, contents: I) -> Self {
98 self.set_parsed_contents(contents);
99 self
100 }
101
102 pub fn item(&self) -> &String {
103 &self.item
104 }
105
106 pub fn item_mut(&mut self) -> &mut String {
107 &mut self.item
108 }
109
110 pub fn url(&self) -> &Url {
111 &self.url
112 }
113
114 pub fn url_mut(&mut self) -> &mut Url {
115 &mut self.url
116 }
117
118 pub fn plugin_name(&self) -> &String {
119 &self.plugin_name
120 }
121
122 pub fn plugin_name_mut(&mut self) -> &mut String {
123 &mut self.plugin_name
124 }
125
126 pub fn maybe_format(&self) -> Option<&String> {
127 self.maybe_format.as_ref()
128 }
129
130 pub fn maybe_format_mut(&mut self) -> &mut Option<String> {
131 &mut self.maybe_format
132 }
133
134 pub fn maybe_contents(&self) -> Option<&String> {
135 self.maybe_contents.as_ref()
136 }
137
138 pub fn maybe_contents_mut(&mut self) -> &mut Option<String> {
139 &mut self.maybe_contents
140 }
141
142 pub fn maybe_parsed_contents(&self) -> Option<&Input> {
143 self.maybe_parsed.as_ref()
144 }
145
146 pub fn maybe_parsed_contents_mut(&mut self) -> &mut Option<Input> {
147 &mut self.maybe_parsed
148 }
149
150 pub fn guess_format(&self, parser_list: &[Box<dyn Parser>]) -> Option<String> {
153 let contents = self.maybe_contents()?;
154 let bytes = contents.as_bytes();
155 if let Some(parser) = parser_list
156 .iter()
157 .find(|parser| parser.is_format_supported(bytes).unwrap_or_default())
158 {
159 parser.supported_format_list().iter().last().cloned()
160 } else {
161 None
162 }
163 }
164
165 pub fn parse_contents(&self, parser_list: &[Box<dyn Parser>]) -> Result<Input, Error> {
166 let contents = if let Some(contents) = self.maybe_contents() {
167 contents
168 } else {
169 return Ok(Input::new_map());
170 };
171 let format = if let Some(format) = self.maybe_format() {
172 format.clone()
173 } else if let Some(format) = self.guess_format(parser_list) {
174 format
175 } else {
176 return Err(Error::ParserNotFound {
177 format: "<unknown>".into(),
178 });
179 };
180 if let Some(parser) = parser_list
181 .iter()
182 .find(|parser| parser.supported_format_list().contains(&format))
183 {
184 parser.parse(contents.as_bytes())
185 } else {
186 Err(Error::ParserNotFound { format })
187 }
188 }
189
190 pub fn parse_contents_mut(
191 &mut self,
192 parser_list: &[Box<dyn Parser>],
193 ) -> Result<&mut Input, Error> {
194 let input = self.parse_contents(parser_list)?;
195 self.set_parsed_contents(input);
196 Ok(self
197 .maybe_parsed_contents_mut()
198 .as_mut()
199 .expect("input has been set!"))
200 }
201}
202
203impl Display for ConfigurationEntity {
204 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
205 f.write_str(format!("Configuration entity for {}", self.plugin_name).as_str())
206 }
207}