use std::fmt::{self, Debug, Display, Formatter}; use gpui::{AbsoluteLength, Axis, Length, Pixels}; use serde::{Deserialize, Serialize}; /// A enum for defining the placement of the element. /// /// See also: [`Side`] if you need to define the left, right side. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum Placement { #[serde(rename = "top")] Top, #[serde(rename = "bottom")] Bottom, #[serde(rename = "left")] Left, #[serde(rename = "right")] Right, } impl Display for Placement { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Placement::Top => write!(f, "Top"), Placement::Bottom => write!(f, "Bottom"), Placement::Left => write!(f, "Left"), Placement::Right => write!(f, "Right"), } } } impl Placement { #[inline] pub fn is_horizontal(&self) -> bool { matches!(self, Placement::Left | Placement::Right) } #[inline] pub fn is_vertical(&self) -> bool { matches!(self, Placement::Top | Placement::Bottom) } #[inline] pub fn axis(&self) -> Axis { match self { Placement::Top | Placement::Bottom => Axis::Vertical, Placement::Left | Placement::Right => Axis::Horizontal, } } } /// A enum for defining the side of the element. /// /// See also: [`Placement`] if you need to define the 4 edges. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum Side { #[serde(rename = "left")] Left, #[serde(rename = "right")] Right, } impl Side { /// Returns true if the side is left. #[inline] pub fn is_left(&self) -> bool { matches!(self, Self::Left) } /// Returns true if the side is right. #[inline] pub fn is_right(&self) -> bool { matches!(self, Self::Right) } } /// A trait to extend the [`Axis`] enum with utility methods. pub trait AxisExt { #[allow(clippy::wrong_self_convention)] fn is_horizontal(self) -> bool; #[allow(clippy::wrong_self_convention)] fn is_vertical(self) -> bool; } impl AxisExt for Axis { #[inline] fn is_horizontal(self) -> bool { self == Axis::Horizontal } #[inline] fn is_vertical(self) -> bool { self == Axis::Vertical } } /// A trait for converting [`Pixels`] to `f32` and `f64`. pub trait PixelsExt { fn as_f32(&self) -> f32; #[allow(clippy::wrong_self_convention)] fn as_f64(self) -> f64; } impl PixelsExt for Pixels { fn as_f32(&self) -> f32 { f32::from(self) } fn as_f64(self) -> f64 { f64::from(self) } } /// A trait to extend the [`Length`] enum with utility methods. pub trait LengthExt { /// Converts the [`Length`] to [`Pixels`] based on a given `base_size` and `rem_size`. /// /// If the [`Length`] is [`Length::Auto`], it returns `None`. fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option; } impl LengthExt for Length { fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Option { match self { Length::Auto => None, Length::Definite(len) => Some(len.to_pixels(base_size, rem_size)), } } } /// A struct for defining the edges of an element. /// /// A extend version of [`gpui::Edges`] to serialize/deserialize. #[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)] #[repr(C)] pub struct Edges { /// The size of the top edge. pub top: T, /// The size of the right edge. pub right: T, /// The size of the bottom edge. pub bottom: T, /// The size of the left edge. pub left: T, } impl Edges where T: Clone + Debug + Default + PartialEq, { /// Creates a new `Edges` instance with all edges set to the same value. pub fn all(value: T) -> Self { Self { top: value.clone(), right: value.clone(), bottom: value.clone(), left: value, } } }