Skip to main content

img_gen_spec/validators/layers/
mod.rs

1mod background;
2mod colors;
3mod ellipse;
4mod icon;
5mod polygon;
6mod rectangle;
7mod size_offset;
8mod typography;
9
10#[cfg(feature = "pyo3")]
11use pyo3::prelude::*;
12
13use serde::{Deserialize, Serialize};
14
15use std::{fmt, num::NonZeroU32};
16
17pub use background::Background;
18pub use colors::{
19    ColorGradient, ColorKind, ConicalGradient, LinearGradient, Presets, RadialGradient, SolidColor,
20    Spread, TRANSPARENT,
21};
22pub use ellipse::{Arc, Ellipse};
23pub use icon::Icon;
24pub use polygon::{IrregularPolygonSides, Polygon, PolygonSides, RegularPolygonSides};
25pub use rectangle::{Corners, Rectangle};
26pub use size_offset::{HEIGHT, LayerOffset, Size, WIDTH};
27pub use typography::{Font, Line, LineHeight, Typography, TypographyAlign, Weight};
28
29/// A property to describe an attributes [`Border`].
30///
31/// See [`Polygon`], [`Rectangle`], [`Ellipse`], and [`Typography`].
32#[cfg_attr(
33    feature = "pyo3",
34    pyclass(module = "img_gen", set_all, get_all, from_py_object)
35)]
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct Border {
38    /// The width (in pixels) used to draw the border.
39    pub width: NonZeroU32,
40    /// The color used to draw the border.
41    #[serde(
42        alias = "linear_gradient",
43        alias = "radial_gradient",
44        alias = "conical_gradient",
45        alias = "linear-gradient",
46        alias = "radial-gradient",
47        alias = "conical-gradient"
48    )]
49    pub color: ColorKind,
50}
51
52/// The default border width in pixels.
53pub const BORDER_WIDTH: NonZeroU32 = NonZeroU32::new(1).unwrap();
54
55impl Default for Border {
56    fn default() -> Self {
57        Self {
58            width: BORDER_WIDTH,
59            color: ColorKind::default(),
60        }
61    }
62}
63
64/// An enum to describe the how to preserve an image's dimensions when portrayed in
65/// an [`Icon`] or [`Background`] attribute.
66#[cfg_attr(
67    feature = "pyo3",
68    pyclass(eq, eq_int, module = "img_gen", from_py_object)
69)]
70#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize)]
71#[serde(rename_all = "lowercase")]
72pub enum PreserveAspect {
73    /// Preserve the original image's aspect ratio with respect to both width and height.
74    #[serde(alias = "true")]
75    #[default]
76    On,
77    /// Ignore the original image's aspect ratio.
78    /// Instead the image will be stretched to the layer's `Size`.
79    #[serde(alias = "false")]
80    Off,
81    /// Preserve the original image's aspect ratio with respect to width.
82    Width,
83    /// Preserve the original image's aspect ratio with respect to height.
84    Height,
85}
86
87impl PreserveAspect {
88    /// Instantiate a [`PreserveAspect`] object from a string.
89    ///
90    /// Possible values include `"true"`, `"false"`, `"width"`, or `"height"`.
91    /// If a given `value` does not match those values (case insensitive), then
92    /// [`PreserveAspect::On`] is returned.
93    pub fn from_string(value: &str) -> PreserveAspect {
94        match value.to_lowercase().as_str() {
95            "false" => PreserveAspect::Off,
96            "width" => PreserveAspect::Width,
97            "height" => PreserveAspect::Height,
98            _ => PreserveAspect::On,
99        }
100    }
101}
102
103impl fmt::Display for PreserveAspect {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            PreserveAspect::On => write!(f, "true"),
107            PreserveAspect::Off => write!(f, "false"),
108            PreserveAspect::Width => write!(f, "width"),
109            PreserveAspect::Height => write!(f, "height"),
110        }
111    }
112}
113
114#[cfg(test)]
115mod test {
116    use super::PreserveAspect;
117
118    #[test]
119    fn test_str() {
120        let str_values = ["true", "false", "width", "height"];
121        for str_val in str_values {
122            let val = PreserveAspect::from_string(str_val).to_string();
123            assert_eq!(val, str_val);
124        }
125        assert_eq!(PreserveAspect::from_string("val").to_string(), "true");
126    }
127}