Add inline xml support for vars
This commit is contained in:
parent
42ae0e6d04
commit
3d5509b570
4 changed files with 51 additions and 20 deletions
|
@ -286,7 +286,7 @@ mod test {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected,
|
expected,
|
||||||
WidgetDefinition::from_xml_element(xml.as_element().unwrap()).unwrap()
|
WidgetDefinition::from_xml_element(xml.as_element().unwrap().to_owned()).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl EwwConfig {
|
||||||
let content = std::fs::read_to_string(path)?;
|
let content = std::fs::read_to_string(path)?;
|
||||||
let document = roxmltree::Document::parse(&content)?;
|
let document = roxmltree::Document::parse(&content)?;
|
||||||
|
|
||||||
let result = EwwConfig::from_xml_element(XmlNode::from(document.root_element()).as_element()?);
|
let result = EwwConfig::from_xml_element(XmlNode::from(document.root_element()).as_element()?.clone());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ impl EwwConfig {
|
||||||
PrimitiveValue::parse_string(
|
PrimitiveValue::parse_string(
|
||||||
&node
|
&node
|
||||||
.only_child()
|
.only_child()
|
||||||
.and_then(|c| Ok(c.as_text()?.text()))
|
.map(|c| c.as_text_or_sourcecode())
|
||||||
.unwrap_or_else(|_| String::new()),
|
.unwrap_or_else(|_| String::new()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@ macro_rules! with_text_pos_context {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum XmlNode<'a, 'b> {
|
pub enum XmlNode<'a, 'b> {
|
||||||
Element(XmlElement<'a, 'b>),
|
Element(XmlElement<'a, 'b>),
|
||||||
Text(XmlText<'a, 'b>),
|
Text(XmlText<'a, 'b>),
|
||||||
|
@ -28,15 +28,44 @@ impl<'a, 'b> fmt::Display for XmlNode<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the part of a string that is selected by the start and end TextPos.
|
||||||
|
/// Will panic if the range is out of bounds in any way.
|
||||||
|
fn get_text_from_text_range(s: &str, (start_pos, end_pos): (roxmltree::TextPos, roxmltree::TextPos)) -> String {
|
||||||
|
let mut code_text = s
|
||||||
|
.lines()
|
||||||
|
.dropping(start_pos.row as usize - 1)
|
||||||
|
.take(end_pos.row as usize - (start_pos.row as usize - 1))
|
||||||
|
.collect_vec();
|
||||||
|
if let Some(first_line) = code_text.first_mut() {
|
||||||
|
*first_line = first_line.split_at(start_pos.col as usize - 1).1;
|
||||||
|
}
|
||||||
|
if let Some(last_line) = code_text.last_mut() {
|
||||||
|
*last_line = last_line.split_at(end_pos.col as usize - 1).0;
|
||||||
|
}
|
||||||
|
code_text.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'b> XmlNode<'a, 'b> {
|
impl<'a, 'b> XmlNode<'a, 'b> {
|
||||||
pub fn as_text(self) -> Result<XmlText<'a, 'b>> {
|
pub fn get_sourcecode(&self) -> String {
|
||||||
|
let input_text = self.node().document().input_text();
|
||||||
|
let range = self.node().range();
|
||||||
|
let start_pos = self.node().document().text_pos_at(range.start);
|
||||||
|
let end_pos = self.node().document().text_pos_at(range.end);
|
||||||
|
get_text_from_text_range(input_text, (start_pos, end_pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_text_or_sourcecode(&self) -> String {
|
||||||
|
self.as_text().map(|c| c.text()).unwrap_or_else(|_| self.get_sourcecode())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_text(&self) -> Result<&XmlText<'a, 'b>> {
|
||||||
match self {
|
match self {
|
||||||
XmlNode::Text(text) => Ok(text),
|
XmlNode::Text(text) => Ok(text),
|
||||||
_ => Err(anyhow!("'{}' is not a text node", self)),
|
_ => Err(anyhow!("'{}' is not a text node", self)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_element(self) -> Result<XmlElement<'a, 'b>> {
|
pub fn as_element(&self) -> Result<&XmlElement<'a, 'b>> {
|
||||||
match self {
|
match self {
|
||||||
XmlNode::Element(element) => Ok(element),
|
XmlNode::Element(element) => Ok(element),
|
||||||
_ => Err(anyhow!("'{}' is not an element node", self)),
|
_ => Err(anyhow!("'{}' is not an element node", self)),
|
||||||
|
@ -62,7 +91,7 @@ impl<'a, 'b> XmlNode<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct XmlText<'a, 'b>(roxmltree::Node<'a, 'b>);
|
pub struct XmlText<'a, 'b>(roxmltree::Node<'a, 'b>);
|
||||||
|
|
||||||
impl<'a, 'b> fmt::Display for XmlText<'a, 'b> {
|
impl<'a, 'b> fmt::Display for XmlText<'a, 'b> {
|
||||||
|
@ -83,7 +112,7 @@ impl<'a, 'b> XmlText<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct XmlElement<'a, 'b>(roxmltree::Node<'a, 'b>);
|
pub struct XmlElement<'a, 'b>(roxmltree::Node<'a, 'b>);
|
||||||
|
|
||||||
impl<'a, 'b> fmt::Display for XmlElement<'a, 'b> {
|
impl<'a, 'b> fmt::Display for XmlElement<'a, 'b> {
|
||||||
|
@ -161,7 +190,7 @@ impl<'a, 'b> XmlElement<'a, 'b> {
|
||||||
|
|
||||||
pub fn only_child_element(&self) -> Result<XmlElement> {
|
pub fn only_child_element(&self) -> Result<XmlElement> {
|
||||||
with_text_pos_context! { self =>
|
with_text_pos_context! { self =>
|
||||||
self.only_child()?.as_element()?
|
self.only_child()?.as_element()?.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,8 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
|
||||||
let widget_definitions = bargs.widget_definitions.clone();
|
let widget_definitions = bargs.widget_definitions.clone();
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
prop(content: as_string) {
|
prop(content: as_string) {
|
||||||
|
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
||||||
|
if !content.is_empty() {
|
||||||
let document = roxmltree::Document::parse(&content)?;
|
let document = roxmltree::Document::parse(&content)?;
|
||||||
let content_widget_use = config::element::WidgetUse::from_xml_node(document.root_element().into())?;
|
let content_widget_use = config::element::WidgetUse::from_xml_node(document.root_element().into())?;
|
||||||
let child_widget = super::widget_use_to_gtk_widget(
|
let child_widget = super::widget_use_to_gtk_widget(
|
||||||
|
@ -155,10 +157,10 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
|
||||||
&std::collections::HashMap::new(),
|
&std::collections::HashMap::new(),
|
||||||
&content_widget_use,
|
&content_widget_use,
|
||||||
)?;
|
)?;
|
||||||
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
|
||||||
gtk_widget.add(&child_widget);
|
gtk_widget.add(&child_widget);
|
||||||
child_widget.show();
|
child_widget.show();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue