accessibility_tree/style/values/
border.rs

1use super::length::*;
2use crate::style::errors::PropertyParseError;
3use cssparser::{Color, Parser};
4
5/// <https://drafts.csswg.org/css-backgrounds/#typedef-line-style>
6#[derive(Copy, Clone, Parse, SpecifiedAsComputed)]
7pub enum LineStyle {
8    None,
9    Solid,
10}
11
12#[derive(Parse)]
13enum ParsedLineWidth {
14    Thin,
15    Medium,
16    Thick,
17    Other(SpecifiedLengthOrPercentage),
18}
19
20#[derive(Clone)]
21pub struct SpecifiedLineWidth(pub SpecifiedLengthOrPercentage);
22
23#[derive(Copy, Clone, FromSpecified)]
24pub struct LineWidth(pub LengthOrPercentage);
25
26impl LineWidth {
27    pub const MEDIUM: Self = LineWidth(LengthOrPercentage::Length(Length { px: 3. }));
28
29    pub fn fixup(&mut self, style: LineStyle) {
30        if let LineStyle::None = style {
31            self.0 = LengthOrPercentage::Length(Length::zero())
32        }
33    }
34}
35
36impl super::Parse for SpecifiedLineWidth {
37    fn parse<'i, 't>(parser: &mut Parser<'i, 't>) -> Result<Self, PropertyParseError<'i>> {
38        let px = match ParsedLineWidth::parse(parser)? {
39            ParsedLineWidth::Thin => 1.0,
40            ParsedLineWidth::Medium => 3.0,
41            ParsedLineWidth::Thick => 5.0,
42            ParsedLineWidth::Other(value) => return Ok(SpecifiedLineWidth(value)),
43        };
44        Ok(SpecifiedLineWidth(
45            SpecifiedLength::Absolute(Length { px }).into(),
46        ))
47    }
48}
49
50macro_rules! parse_one_or_more {
51    ($type: ty { $( $field: ident, )+ }) => {
52        impl crate::style::values::Parse for BorderSide {
53            fn parse<'i, 't>(parser: &mut Parser<'i, 't>)
54                -> Result<Self, PropertyParseError<'i>>
55            {
56                let mut values = Self::default();
57                let mut any = false;
58                loop {
59                    $(
60                        if values.$field.is_none() {
61                            if let Ok(value) = parser.r#try(crate::style::values::Parse::parse) {
62                                values.$field = Some(value);
63                                any = true;
64                                continue
65                            }
66                        }
67                    )+
68                    break
69                }
70                if any {
71                    Ok(values)
72                } else {
73                    Err(parser.new_error_for_next_token())
74                }
75            }
76        }
77    };
78}
79
80parse_one_or_more!(BorderSide {
81    style,
82    color,
83    width,
84});
85
86#[derive(Default)]
87pub struct BorderSide {
88    pub style: Option<LineStyle>,
89    pub color: Option<Color>,
90    pub width: Option<SpecifiedLineWidth>,
91}