Added layout properties
This commit is contained in:
parent
12e15321a4
commit
57756d8048
8 changed files with 203 additions and 31 deletions
|
@ -325,7 +325,7 @@ impl CodeRule {
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
],
|
],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ impl GraphRule {
|
||||||
r"\[graph\](?:\[((?:\\.|[^\[\]\\])*?)\])?(?:((?:\\.|[^\\\\])*?)\[/graph\])?",
|
r"\[graph\](?:\[((?:\\.|[^\[\]\\])*?)\])?(?:((?:\\.|[^\\\\])*?)\[/graph\])?",
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@ use crate::document::document::Document;
|
||||||
use crate::document::element::ElemKind;
|
use crate::document::element::ElemKind;
|
||||||
use crate::document::element::Element;
|
use crate::document::element::Element;
|
||||||
use crate::parser::parser::Parser;
|
use crate::parser::parser::Parser;
|
||||||
|
use crate::parser::parser::ReportColors;
|
||||||
use crate::parser::rule::RegexRule;
|
use crate::parser::rule::RegexRule;
|
||||||
use crate::parser::source::Source;
|
use crate::parser::source::Source;
|
||||||
use crate::parser::source::Token;
|
use crate::parser::source::Token;
|
||||||
use crate::parser::state::Scope;
|
use crate::parser::state::Scope;
|
||||||
use crate::parser::state::State;
|
use crate::parser::state::State;
|
||||||
|
use crate::parser::util::process_escaped;
|
||||||
use ariadne::Fmt;
|
use ariadne::Fmt;
|
||||||
use ariadne::Label;
|
use ariadne::Label;
|
||||||
use ariadne::Report;
|
use ariadne::Report;
|
||||||
|
@ -17,7 +19,9 @@ use lazy_static::lazy_static;
|
||||||
use mlua::Function;
|
use mlua::Function;
|
||||||
use mlua::Lua;
|
use mlua::Lua;
|
||||||
use regex::Captures;
|
use regex::Captures;
|
||||||
|
use regex::Match;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use std::any::Any;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
@ -35,6 +39,9 @@ pub trait LayoutType: core::fmt::Debug {
|
||||||
/// Name of the layout
|
/// Name of the layout
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// Parses layout properties
|
||||||
|
fn parse_properties(&self, properties: &str) -> Result<Option<Box<dyn Any>>, String>;
|
||||||
|
|
||||||
/// Expected number of blocks
|
/// Expected number of blocks
|
||||||
fn expects(&self) -> Range<usize>;
|
fn expects(&self) -> Range<usize>;
|
||||||
|
|
||||||
|
@ -43,15 +50,21 @@ pub trait LayoutType: core::fmt::Debug {
|
||||||
&self,
|
&self,
|
||||||
token: LayoutToken,
|
token: LayoutToken,
|
||||||
id: usize,
|
id: usize,
|
||||||
|
properties: &Option<Box<dyn Any>>,
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
document: &dyn Document,
|
document: &dyn Document,
|
||||||
) -> Result<String, String>;
|
) -> Result<String, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod default_layouts {
|
mod default_layouts {
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
use crate::parser::util::Property;
|
||||||
|
use crate::parser::util::PropertyParser;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Centered;
|
pub struct Centered;
|
||||||
|
|
||||||
impl LayoutType for Centered {
|
impl LayoutType for Centered {
|
||||||
|
@ -59,10 +72,18 @@ mod default_layouts {
|
||||||
|
|
||||||
fn expects(&self) -> Range<usize> { 1..1 }
|
fn expects(&self) -> Range<usize> { 1..1 }
|
||||||
|
|
||||||
|
fn parse_properties(&self, properties: &str) -> Result<Option<Box<dyn Any>>, String> {
|
||||||
|
if !properties.is_empty() {
|
||||||
|
return Err(format!("Layout {} excepts no properties", self.name()));
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
fn compile(
|
fn compile(
|
||||||
&self,
|
&self,
|
||||||
token: LayoutToken,
|
token: LayoutToken,
|
||||||
_id: usize,
|
_id: usize,
|
||||||
|
_properties: &Option<Box<dyn Any>>,
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
_document: &dyn Document,
|
_document: &dyn Document,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
|
@ -78,26 +99,83 @@ mod default_layouts {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Split;
|
pub struct Split {
|
||||||
|
properties: PropertyParser,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Split {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut properties = HashMap::new();
|
||||||
|
properties.insert(
|
||||||
|
"style".to_string(),
|
||||||
|
Property::new(
|
||||||
|
true,
|
||||||
|
"Additional style for the split".to_string(),
|
||||||
|
Some("".to_string()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
properties: PropertyParser { properties },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LayoutType for Split {
|
impl LayoutType for Split {
|
||||||
fn name(&self) -> &'static str { "Split" }
|
fn name(&self) -> &'static str { "Split" }
|
||||||
|
|
||||||
fn expects(&self) -> Range<usize> { 2..usize::MAX }
|
fn expects(&self) -> Range<usize> { 2..usize::MAX }
|
||||||
|
|
||||||
|
fn parse_properties(&self, properties: &str) -> Result<Option<Box<dyn Any>>, String> {
|
||||||
|
let props = if properties.is_empty() {
|
||||||
|
self.properties.default()
|
||||||
|
} else {
|
||||||
|
self.properties.parse(properties)
|
||||||
|
}
|
||||||
|
.map_err(|err| {
|
||||||
|
format!(
|
||||||
|
"Failed to parse properties for layout {}: {err}",
|
||||||
|
self.name()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let style = props
|
||||||
|
.get("style", |_, value| -> Result<String, ()> {
|
||||||
|
Ok(value.clone())
|
||||||
|
})
|
||||||
|
.map_err(|err| format!("Failed to parse style: {err:#?}"))
|
||||||
|
.map(|(_, value)| value)?;
|
||||||
|
|
||||||
|
Ok(Some(Box::new(style)))
|
||||||
|
}
|
||||||
|
|
||||||
fn compile(
|
fn compile(
|
||||||
&self,
|
&self,
|
||||||
token: LayoutToken,
|
token: LayoutToken,
|
||||||
_id: usize,
|
_id: usize,
|
||||||
|
properties: &Option<Box<dyn Any>>,
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
_document: &dyn Document,
|
_document: &dyn Document,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
match compiler.target() {
|
match compiler.target() {
|
||||||
Target::HTML => match token {
|
Target::HTML => {
|
||||||
LayoutToken::BEGIN => Ok(r#"<div class="split-container"><div class="split">"#.to_string()),
|
let style = match properties
|
||||||
LayoutToken::NEXT => Ok(r#"</div><div class="split">"#.to_string()),
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.downcast_ref::<String>()
|
||||||
|
.unwrap().as_str()
|
||||||
|
{
|
||||||
|
"" => "".to_string(),
|
||||||
|
str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str))
|
||||||
|
};
|
||||||
|
match token {
|
||||||
|
LayoutToken::BEGIN => Ok(format!(
|
||||||
|
r#"<div class="split-container"><div class="split"{style}>"#
|
||||||
|
)),
|
||||||
|
LayoutToken::NEXT => Ok(format!(r#"</div><div class="split"{style}>"#)),
|
||||||
LayoutToken::END => Ok(r#"</div></div>"#.to_string()),
|
LayoutToken::END => Ok(r#"</div></div>"#.to_string()),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => todo!(""),
|
_ => todo!(""),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +188,7 @@ struct Layout {
|
||||||
pub(self) layout: Rc<dyn LayoutType>,
|
pub(self) layout: Rc<dyn LayoutType>,
|
||||||
pub(self) id: usize,
|
pub(self) id: usize,
|
||||||
pub(self) token: LayoutToken,
|
pub(self) token: LayoutToken,
|
||||||
|
pub(self) properties: Option<Box<dyn Any>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Layout {
|
impl Element for Layout {
|
||||||
|
@ -118,7 +197,8 @@ impl Element for Layout {
|
||||||
fn element_name(&self) -> &'static str { "Layout" }
|
fn element_name(&self) -> &'static str { "Layout" }
|
||||||
fn to_string(&self) -> String { format!("{self:#?}") }
|
fn to_string(&self) -> String { format!("{self:#?}") }
|
||||||
fn compile(&self, compiler: &Compiler, document: &dyn Document) -> Result<String, String> {
|
fn compile(&self, compiler: &Compiler, document: &dyn Document) -> Result<String, String> {
|
||||||
self.layout.compile(self.token, self.id, compiler, document)
|
self.layout
|
||||||
|
.compile(self.token, self.id, &self.properties, compiler, document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,20 +262,64 @@ pub struct LayoutRule {
|
||||||
impl LayoutRule {
|
impl LayoutRule {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut layouts: HashMap<String, Rc<dyn LayoutType>> = HashMap::new();
|
let mut layouts: HashMap<String, Rc<dyn LayoutType>> = HashMap::new();
|
||||||
let layout_centered = default_layouts::Centered {};
|
|
||||||
|
let layout_centered = default_layouts::Centered::default();
|
||||||
layouts.insert(layout_centered.name().to_string(), Rc::new(layout_centered));
|
layouts.insert(layout_centered.name().to_string(), Rc::new(layout_centered));
|
||||||
let layout_split = default_layouts::Split {};
|
|
||||||
|
let layout_split = default_layouts::Split::default();
|
||||||
layouts.insert(layout_split.name().to_string(), Rc::new(layout_split));
|
layouts.insert(layout_split.name().to_string(), Rc::new(layout_split));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
re: [
|
re: [
|
||||||
Regex::new(r"(?:^|\n)#\+LAYOUT_BEGIN(.*)").unwrap(),
|
Regex::new(r"(?:^|\n)#\+LAYOUT_BEGIN(?:\[((?:\\.|[^\\\\])*?)\])?(.*)").unwrap(),
|
||||||
Regex::new(r"(?:^|\n)#\+LAYOUT_NEXT(?:$|\n)").unwrap(),
|
Regex::new(r"(?:^|\n)#\+LAYOUT_NEXT(?:\[((?:\\.|[^\\\\])*?)\])?(?:$|\n)").unwrap(),
|
||||||
Regex::new(r"(?:^|\n)#\+LAYOUT_END(?:$|\n)").unwrap(),
|
Regex::new(r"(?:^|\n)#\+LAYOUT_END(?:\[((?:\\.|[^\\\\])*?)\])?(?:$|\n)").unwrap(),
|
||||||
],
|
],
|
||||||
layouts,
|
layouts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_properties<'a>(
|
||||||
|
colors: &ReportColors,
|
||||||
|
token: &Token,
|
||||||
|
layout_type: Rc<dyn LayoutType>,
|
||||||
|
properties: Option<Match>,
|
||||||
|
) -> Result<Option<Box<dyn Any>>, Report<'a, (Rc<dyn Source>, Range<usize>)>> {
|
||||||
|
match properties {
|
||||||
|
None => match layout_type.parse_properties("") {
|
||||||
|
Ok(props) => Ok(props),
|
||||||
|
Err(err) => Err(
|
||||||
|
Report::build(ReportKind::Error, token.source(), token.start())
|
||||||
|
.with_message("Unable to parse layout properties")
|
||||||
|
.with_label(
|
||||||
|
Label::new((token.source(), token.range.clone()))
|
||||||
|
.with_message(err)
|
||||||
|
.with_color(colors.error),
|
||||||
|
)
|
||||||
|
.finish(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Some(props) => {
|
||||||
|
let trimmed = props.as_str().trim_start().trim_end();
|
||||||
|
let content = process_escaped('\\', "]", trimmed);
|
||||||
|
match layout_type.parse_properties(content.as_str()) {
|
||||||
|
Ok(props) => Ok(props),
|
||||||
|
Err(err) => {
|
||||||
|
Err(
|
||||||
|
Report::build(ReportKind::Error, token.source(), props.start())
|
||||||
|
.with_message("Unable to parse layout properties")
|
||||||
|
.with_label(
|
||||||
|
Label::new((token.source(), props.range()))
|
||||||
|
.with_message(err)
|
||||||
|
.with_color(colors.error),
|
||||||
|
)
|
||||||
|
.finish(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -235,7 +359,7 @@ impl RegexRule for LayoutRule {
|
||||||
if index == 0
|
if index == 0
|
||||||
// BEGIN_LAYOUT
|
// BEGIN_LAYOUT
|
||||||
{
|
{
|
||||||
match matches.get(1) {
|
match matches.get(2) {
|
||||||
None => {
|
None => {
|
||||||
reports.push(
|
reports.push(
|
||||||
Report::build(ReportKind::Error, token.source(), token.start())
|
Report::build(ReportKind::Error, token.source(), token.start())
|
||||||
|
@ -276,11 +400,11 @@ impl RegexRule for LayoutRule {
|
||||||
{
|
{
|
||||||
reports.push(
|
reports.push(
|
||||||
Report::build(ReportKind::Error, token.source(), name.start())
|
Report::build(ReportKind::Error, token.source(), name.start())
|
||||||
.with_message("Empty Layout Name")
|
.with_message("Invalid Layout Name")
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::new((token.source(), name.range()))
|
Label::new((token.source(), name.range()))
|
||||||
.with_message(format!(
|
.with_message(format!(
|
||||||
"Missing a space before layout `{}`",
|
"Missing a space before layout name `{}`",
|
||||||
name.as_str().fg(parser.colors().highlight)
|
name.as_str().fg(parser.colors().highlight)
|
||||||
))
|
))
|
||||||
.with_color(parser.colors().error),
|
.with_color(parser.colors().error),
|
||||||
|
@ -311,6 +435,20 @@ impl RegexRule for LayoutRule {
|
||||||
Some(layout_type) => layout_type,
|
Some(layout_type) => layout_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Parse properties
|
||||||
|
let properties = match LayoutRule::parse_properties(
|
||||||
|
parser.colors(),
|
||||||
|
&token,
|
||||||
|
layout_type.clone(),
|
||||||
|
matches.get(1),
|
||||||
|
) {
|
||||||
|
Ok(props) => props,
|
||||||
|
Err(rep) => {
|
||||||
|
reports.push(rep);
|
||||||
|
return reports;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
parser.push(
|
parser.push(
|
||||||
document,
|
document,
|
||||||
Box::new(Layout {
|
Box::new(Layout {
|
||||||
|
@ -318,6 +456,7 @@ impl RegexRule for LayoutRule {
|
||||||
layout: layout_type.clone(),
|
layout: layout_type.clone(),
|
||||||
id: 0,
|
id: 0,
|
||||||
token: LayoutToken::BEGIN,
|
token: LayoutToken::BEGIN,
|
||||||
|
properties,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -333,7 +472,7 @@ impl RegexRule for LayoutRule {
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (id, token_type, layout_type) = if index == 1
|
let (id, token_type, layout_type, properties) = if index == 1
|
||||||
// LAYOUT_NEXT
|
// LAYOUT_NEXT
|
||||||
{
|
{
|
||||||
let mut state_borrow = state.borrow_mut();
|
let mut state_borrow = state.borrow_mut();
|
||||||
|
@ -376,8 +515,27 @@ impl RegexRule for LayoutRule {
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse properties
|
||||||
|
let properties = match LayoutRule::parse_properties(
|
||||||
|
parser.colors(),
|
||||||
|
&token,
|
||||||
|
layout_type.clone(),
|
||||||
|
matches.get(1),
|
||||||
|
) {
|
||||||
|
Ok(props) => props,
|
||||||
|
Err(rep) => {
|
||||||
|
reports.push(rep);
|
||||||
|
return reports;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
tokens.push(token.clone());
|
tokens.push(token.clone());
|
||||||
(tokens.len() - 1, LayoutToken::NEXT, layout_type.clone())
|
(
|
||||||
|
tokens.len() - 1,
|
||||||
|
LayoutToken::NEXT,
|
||||||
|
layout_type.clone(),
|
||||||
|
properties,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// LAYOUT_END
|
// LAYOUT_END
|
||||||
let mut state_borrow = state.borrow_mut();
|
let mut state_borrow = state.borrow_mut();
|
||||||
|
@ -420,10 +578,24 @@ impl RegexRule for LayoutRule {
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse properties
|
||||||
|
let properties = match LayoutRule::parse_properties(
|
||||||
|
parser.colors(),
|
||||||
|
&token,
|
||||||
|
layout_type.clone(),
|
||||||
|
matches.get(1),
|
||||||
|
) {
|
||||||
|
Ok(props) => props,
|
||||||
|
Err(rep) => {
|
||||||
|
reports.push(rep);
|
||||||
|
return reports;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let layout_type = layout_type.clone();
|
let layout_type = layout_type.clone();
|
||||||
let id = tokens.len();
|
let id = tokens.len();
|
||||||
state.stack.pop();
|
state.stack.pop();
|
||||||
(id, LayoutToken::END, layout_type)
|
(id, LayoutToken::END, layout_type, properties)
|
||||||
};
|
};
|
||||||
|
|
||||||
parser.push(
|
parser.push(
|
||||||
|
@ -433,6 +605,7 @@ impl RegexRule for LayoutRule {
|
||||||
layout: layout_type,
|
layout: layout_type,
|
||||||
id,
|
id,
|
||||||
token: token_type,
|
token: token_type,
|
||||||
|
properties,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ impl MediaRule {
|
||||||
.multi_line(true)
|
.multi_line(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl RawRule {
|
||||||
Regex::new(r"\{\?(?:\[((?:\\.|[^\[\]\\])*?)\])?(?:((?:\\.|[^\\\\])*?)(\?\}))?")
|
Regex::new(r"\{\?(?:\[((?:\\.|[^\[\]\\])*?)\])?(?:((?:\\.|[^\\\\])*?)(\?\}))?")
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
],
|
],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl ReferenceRule {
|
||||||
);
|
);
|
||||||
Self {
|
Self {
|
||||||
re: [Regex::new(r"§\{(.*)\}(\[((?:\\.|[^\\\\])*?)\])?").unwrap()],
|
re: [Regex::new(r"§\{(.*)\}(\[((?:\\.|[^\\\\])*?)\])?").unwrap()],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ impl TexRule {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Regex::new(r"\$(?:\[((?:\\.|[^\\\\])*?)\])?(?:((?:\\.|[^\\\\])*?)\$)?").unwrap(),
|
Regex::new(r"\$(?:\[((?:\\.|[^\\\\])*?)\])?(?:((?:\\.|[^\\\\])*?)\$)?").unwrap(),
|
||||||
],
|
],
|
||||||
properties: PropertyParser::new(props),
|
properties: PropertyParser{ properties: props },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,13 +229,12 @@ impl<'a> PropertyMap<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct PropertyParser {
|
pub struct PropertyParser {
|
||||||
properties: HashMap<String, Property>,
|
pub properties: HashMap<String, Property>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PropertyParser {
|
impl PropertyParser {
|
||||||
pub fn new(properties: HashMap<String, Property>) -> Self { Self { properties } }
|
|
||||||
|
|
||||||
/// Attempts to build a default propertymap
|
/// Attempts to build a default propertymap
|
||||||
///
|
///
|
||||||
/// Returns an error if at least one [`Property`] is required and doesn't provide a default
|
/// Returns an error if at least one [`Property`] is required and doesn't provide a default
|
||||||
|
@ -271,7 +270,7 @@ impl PropertyParser {
|
||||||
/// properties.insert("width".to_string(),
|
/// properties.insert("width".to_string(),
|
||||||
/// Property::new(true, "Width of the element in em".to_string(), None));
|
/// Property::new(true, "Width of the element in em".to_string(), None));
|
||||||
///
|
///
|
||||||
/// let parser = PropertyParser::new(properties);
|
/// let parser = PropertyParser { properties };
|
||||||
/// let pm = parser.parse("width=15").unwrap();
|
/// let pm = parser.parse("width=15").unwrap();
|
||||||
///
|
///
|
||||||
/// assert_eq!(pm.get("width", |_, s| s.parse::<i32>()).unwrap().1, 15);
|
/// assert_eq!(pm.get("width", |_, s| s.parse::<i32>()).unwrap().1, 15);
|
||||||
|
@ -491,7 +490,7 @@ mod tests {
|
||||||
Property::new(false, "Weight in %".to_string(), Some("0.42".to_string())),
|
Property::new(false, "Weight in %".to_string(), Some("0.42".to_string())),
|
||||||
);
|
);
|
||||||
|
|
||||||
let parser = PropertyParser::new(properties);
|
let parser = PropertyParser { properties };
|
||||||
let pm = parser.parse("width=15,length=-10").unwrap();
|
let pm = parser.parse("width=15,length=-10").unwrap();
|
||||||
|
|
||||||
// Ok
|
// Ok
|
||||||
|
|
Loading…
Reference in a new issue