use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FlexStyle {
pub display: Display,
pub position: Position,
pub overflow: Overflow,
pub flex_direction: FlexDirection,
pub flex_wrap: FlexWrap,
pub justify_content: JustifyContent,
pub align_items: AlignItems,
pub align_content: AlignContent,
pub flex_grow: f32,
pub flex_shrink: f32,
pub flex_basis: Dimension,
pub align_self: AlignSelf,
pub width: Dimension,
pub height: Dimension,
pub min_width: Dimension,
pub min_height: Dimension,
pub max_width: Dimension,
pub max_height: Dimension,
pub margin: Edges,
pub padding: Edges,
pub gap: Gap,
pub border: Edges,
pub inset: Inset,
}
impl Default for FlexStyle {
fn default() -> Self {
Self {
display: Display::default(),
position: Position::default(),
overflow: Overflow::default(),
flex_direction: FlexDirection::default(),
flex_wrap: FlexWrap::default(),
justify_content: JustifyContent::default(),
align_items: AlignItems::default(),
align_content: AlignContent::default(),
flex_grow: 0.0,
flex_shrink: 1.0, flex_basis: Dimension::default(),
align_self: AlignSelf::default(),
width: Dimension::default(),
height: Dimension::default(),
min_width: Dimension::default(),
min_height: Dimension::default(),
max_width: Dimension::default(),
max_height: Dimension::default(),
margin: Edges::default(),
padding: Edges::default(),
gap: Gap::default(),
border: Edges::default(),
inset: Inset::default(),
}
}
}
impl FlexStyle {
pub fn new() -> Self {
Self::default()
}
pub fn to_taffy(&self) -> taffy::Style {
taffy::Style {
display: self.display.to_taffy(),
position: self.position.to_taffy(),
overflow: taffy::Point {
x: self.overflow.to_taffy(),
y: self.overflow.to_taffy(),
},
flex_direction: self.flex_direction.to_taffy(),
flex_wrap: self.flex_wrap.to_taffy(),
justify_items: Some(taffy::JustifyItems::Start),
justify_self: Some(taffy::JustifySelf::Start),
justify_content: Some(self.justify_content.to_taffy()),
align_items: Some(self.align_items.to_taffy()),
align_self: self.align_self.to_taffy(),
align_content: Some(self.align_content.to_taffy()),
flex_grow: self.flex_grow,
flex_shrink: self.flex_shrink,
flex_basis: self.flex_basis.to_taffy(),
size: taffy::Size {
width: self.width.to_taffy(),
height: self.height.to_taffy(),
},
min_size: taffy::Size {
width: self.min_width.to_taffy(),
height: self.min_height.to_taffy(),
},
max_size: taffy::Size {
width: self.max_width.to_taffy(),
height: self.max_height.to_taffy(),
},
aspect_ratio: None,
margin: self.margin.to_taffy(),
padding: self.padding.to_taffy_no_auto(),
gap: self.gap.to_taffy(),
border: self.border.to_taffy_no_auto(),
inset: self.inset.to_taffy(),
scrollbar_width: 0.0,
..Default::default()
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum Display {
#[default]
Flex,
None,
}
impl Display {
fn to_taffy(self) -> taffy::Display {
match self {
Display::Flex => taffy::Display::Flex,
Display::None => taffy::Display::None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum Position {
#[default]
Relative,
Absolute,
}
impl Position {
fn to_taffy(self) -> taffy::Position {
match self {
Position::Relative => taffy::Position::Relative,
Position::Absolute => taffy::Position::Absolute,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum Overflow {
#[default]
Visible,
Hidden,
Scroll,
}
impl Overflow {
fn to_taffy(self) -> taffy::Overflow {
match self {
Overflow::Visible => taffy::Overflow::Visible,
Overflow::Hidden => taffy::Overflow::Hidden,
Overflow::Scroll => taffy::Overflow::Scroll,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum FlexDirection {
#[default]
Row,
Column,
RowReverse,
ColumnReverse,
}
impl FlexDirection {
fn to_taffy(self) -> taffy::FlexDirection {
match self {
FlexDirection::Row => taffy::FlexDirection::Row,
FlexDirection::Column => taffy::FlexDirection::Column,
FlexDirection::RowReverse => taffy::FlexDirection::RowReverse,
FlexDirection::ColumnReverse => taffy::FlexDirection::ColumnReverse,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum FlexWrap {
#[default]
NoWrap,
Wrap,
WrapReverse,
}
impl FlexWrap {
fn to_taffy(self) -> taffy::FlexWrap {
match self {
FlexWrap::NoWrap => taffy::FlexWrap::NoWrap,
FlexWrap::Wrap => taffy::FlexWrap::Wrap,
FlexWrap::WrapReverse => taffy::FlexWrap::WrapReverse,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum JustifyContent {
#[default]
FlexStart,
FlexEnd,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
impl JustifyContent {
fn to_taffy(self) -> taffy::JustifyContent {
match self {
JustifyContent::FlexStart => taffy::JustifyContent::FlexStart,
JustifyContent::FlexEnd => taffy::JustifyContent::FlexEnd,
JustifyContent::Center => taffy::JustifyContent::Center,
JustifyContent::SpaceBetween => taffy::JustifyContent::SpaceBetween,
JustifyContent::SpaceAround => taffy::JustifyContent::SpaceAround,
JustifyContent::SpaceEvenly => taffy::JustifyContent::SpaceEvenly,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum AlignItems {
Stretch,
#[default]
FlexStart,
FlexEnd,
Center,
Baseline,
}
impl AlignItems {
fn to_taffy(self) -> taffy::AlignItems {
match self {
AlignItems::Stretch => taffy::AlignItems::Stretch,
AlignItems::FlexStart => taffy::AlignItems::FlexStart,
AlignItems::FlexEnd => taffy::AlignItems::FlexEnd,
AlignItems::Center => taffy::AlignItems::Center,
AlignItems::Baseline => taffy::AlignItems::Baseline,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum AlignContent {
Stretch,
#[default]
FlexStart,
FlexEnd,
Center,
SpaceBetween,
SpaceAround,
}
impl AlignContent {
fn to_taffy(self) -> taffy::AlignContent {
match self {
AlignContent::Stretch => taffy::AlignContent::Stretch,
AlignContent::FlexStart => taffy::AlignContent::FlexStart,
AlignContent::FlexEnd => taffy::AlignContent::FlexEnd,
AlignContent::Center => taffy::AlignContent::Center,
AlignContent::SpaceBetween => taffy::AlignContent::SpaceBetween,
AlignContent::SpaceAround => taffy::AlignContent::SpaceAround,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum AlignSelf {
#[default]
Auto,
Stretch,
FlexStart,
FlexEnd,
Center,
Baseline,
}
impl AlignSelf {
fn to_taffy(self) -> Option<taffy::AlignSelf> {
match self {
AlignSelf::Auto => None,
AlignSelf::Stretch => Some(taffy::AlignSelf::Stretch),
AlignSelf::FlexStart => Some(taffy::AlignSelf::FlexStart),
AlignSelf::FlexEnd => Some(taffy::AlignSelf::FlexEnd),
AlignSelf::Center => Some(taffy::AlignSelf::Center),
AlignSelf::Baseline => Some(taffy::AlignSelf::Baseline),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
pub enum Dimension {
#[default]
Auto,
Points(f32),
Percent(f32),
}
impl Dimension {
pub fn points(value: f32) -> Self {
Dimension::Points(value)
}
pub fn percent(value: f32) -> Self {
Dimension::Percent(value)
}
fn to_taffy(self) -> taffy::Dimension {
match self {
Dimension::Auto => taffy::Dimension::Auto,
Dimension::Points(v) => taffy::Dimension::Length(v),
Dimension::Percent(v) => taffy::Dimension::Percent(v / 100.0),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
pub struct Edges {
pub top: LengthPercentageAuto,
pub right: LengthPercentageAuto,
pub bottom: LengthPercentageAuto,
pub left: LengthPercentageAuto,
}
impl Edges {
pub fn all(value: f32) -> Self {
Self {
top: LengthPercentageAuto::Points(value),
right: LengthPercentageAuto::Points(value),
bottom: LengthPercentageAuto::Points(value),
left: LengthPercentageAuto::Points(value),
}
}
pub fn symmetric(vertical: f32, horizontal: f32) -> Self {
Self {
top: LengthPercentageAuto::Points(vertical),
right: LengthPercentageAuto::Points(horizontal),
bottom: LengthPercentageAuto::Points(vertical),
left: LengthPercentageAuto::Points(horizontal),
}
}
fn to_taffy(self) -> taffy::Rect<taffy::LengthPercentageAuto> {
taffy::Rect {
top: self.top.to_taffy(),
right: self.right.to_taffy(),
bottom: self.bottom.to_taffy(),
left: self.left.to_taffy(),
}
}
fn to_taffy_no_auto(self) -> taffy::Rect<taffy::LengthPercentage> {
taffy::Rect {
top: self.top.to_taffy_no_auto(),
right: self.right.to_taffy_no_auto(),
bottom: self.bottom.to_taffy_no_auto(),
left: self.left.to_taffy_no_auto(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
pub enum LengthPercentageAuto {
#[default]
Auto,
Points(f32),
Percent(f32),
}
impl LengthPercentageAuto {
fn to_taffy(self) -> taffy::LengthPercentageAuto {
match self {
LengthPercentageAuto::Auto => taffy::LengthPercentageAuto::Auto,
LengthPercentageAuto::Points(v) => taffy::LengthPercentageAuto::Length(v),
LengthPercentageAuto::Percent(v) => taffy::LengthPercentageAuto::Percent(v / 100.0),
}
}
fn to_taffy_no_auto(self) -> taffy::LengthPercentage {
match self {
LengthPercentageAuto::Auto => taffy::LengthPercentage::Length(0.0),
LengthPercentageAuto::Points(v) => taffy::LengthPercentage::Length(v),
LengthPercentageAuto::Percent(v) => taffy::LengthPercentage::Percent(v / 100.0),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
pub struct Gap {
pub row: f32,
pub column: f32,
}
impl Gap {
pub fn all(value: f32) -> Self {
Self {
row: value,
column: value,
}
}
fn to_taffy(self) -> taffy::Size<taffy::LengthPercentage> {
taffy::Size {
width: taffy::LengthPercentage::Length(self.column),
height: taffy::LengthPercentage::Length(self.row),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
pub struct Inset {
pub top: LengthPercentageAuto,
pub right: LengthPercentageAuto,
pub bottom: LengthPercentageAuto,
pub left: LengthPercentageAuto,
}
impl Inset {
fn to_taffy(self) -> taffy::Rect<taffy::LengthPercentageAuto> {
taffy::Rect {
top: self.top.to_taffy(),
right: self.right.to_taffy(),
bottom: self.bottom.to_taffy(),
left: self.left.to_taffy(),
}
}
}
#[cfg(test)]
mod tests {
use super::{Dimension, Display, Edges, FlexDirection, FlexStyle, LengthPercentageAuto};
#[test]
fn test_flex_style_default() {
let style = FlexStyle::new();
assert_eq!(style.flex_direction, FlexDirection::Row);
assert_eq!(style.display, Display::Flex);
}
#[test]
fn test_flex_style_to_taffy() {
let mut style = FlexStyle::new();
style.flex_direction = FlexDirection::Column;
style.width = Dimension::Points(100.0);
let taffy_style = style.to_taffy();
assert_eq!(taffy_style.flex_direction, taffy::FlexDirection::Column);
}
#[test]
fn test_edges_all() {
let edges = Edges::all(10.0);
assert_eq!(edges.top, LengthPercentageAuto::Points(10.0));
assert_eq!(edges.right, LengthPercentageAuto::Points(10.0));
}
}