freya_core/values/
size.rs1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 character::complete::multispace0,
5 combinator::map,
6 multi::many1,
7 number::complete::float,
8 sequence::{
9 preceded,
10 tuple,
11 },
12 IResult,
13};
14use torin::{
15 geometry::Length,
16 size::{
17 DynamicCalculation,
18 Size,
19 },
20};
21
22use crate::parsing::{
23 Parse,
24 ParseError,
25};
26
27impl Parse for Size {
28 fn parse(value: &str) -> Result<Self, ParseError> {
29 if value == "auto" {
30 Ok(Size::Inner)
31 } else if value == "flex" {
32 Ok(Size::Flex(Length::new(1.0)))
33 } else if value.contains("flex") {
34 Ok(Size::Flex(Length::new(
35 value
36 .replace("flex(", "")
37 .replace(')', "")
38 .parse::<f32>()
39 .map_err(|_| ParseError)?,
40 )))
41 } else if value == "fill" {
42 Ok(Size::Fill)
43 } else if value == "fill-min" {
44 Ok(Size::FillMinimum)
45 } else if value.contains("calc") {
46 Ok(Size::DynamicCalculations(1.0, Box::new(parse_calc(value)?)))
47 } else if value.contains('%') {
48 Ok(Size::Percentage(Length::new(
49 value
50 .replace('%', "")
51 .parse::<f32>()
52 .map_err(|_| ParseError)?,
53 )))
54 } else if value.contains('v') {
55 Ok(Size::RootPercentage(Length::new(
56 value
57 .replace('v', "")
58 .parse::<f32>()
59 .map_err(|_| ParseError)?,
60 )))
61 } else {
62 Ok(Size::Pixels(Length::new(
63 value.parse::<f32>().map_err(|_| ParseError)?,
64 )))
65 }
66 }
67}
68
69pub fn parse_calc(mut value: &str) -> Result<Vec<DynamicCalculation>, ParseError> {
70 value = value
73 .strip_prefix("calc(")
74 .ok_or(ParseError)?
75 .strip_suffix(')')
76 .ok_or(ParseError)?;
77 fn inner_parse(value: &str) -> IResult<&str, Vec<DynamicCalculation>> {
78 many1(preceded(
79 multispace0,
80 alt((
81 map(tag("+"), |_| DynamicCalculation::Add),
82 map(tag("-"), |_| DynamicCalculation::Sub),
83 map(tag("*"), |_| DynamicCalculation::Mul),
84 map(tag("/"), |_| DynamicCalculation::Div),
85 map(tag("("), |_| DynamicCalculation::OpenParenthesis),
86 map(tag(")"), |_| DynamicCalculation::ClosedParenthesis),
87 map(tuple((float, tag("%"))), |(v, _)| {
88 DynamicCalculation::Percentage(v)
89 }),
90 map(tuple((float, tag("v"))), |(v, _)| {
91 DynamicCalculation::RootPercentage(v)
92 }),
93 map(float, DynamicCalculation::Pixels),
94 )),
95 ))(value)
96 }
97 let tokens = inner_parse(value).map_err(|_| ParseError)?.1;
98
99 Ok(tokens)
100}