use std::marker::PhantomData;
pub struct Dialog<Node, Message> {
pub content: Node,
_marker: PhantomData<Message>,
}
impl<Node, Message> Dialog<Node, Message> {
pub fn new(content: Node) -> Self {
Self {
content,
_marker: PhantomData,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum SheetEdge {
#[default]
Bottom,
Top,
Start,
End,
}
impl SheetEdge {
#[must_use]
pub fn is_vertical(self) -> bool {
matches!(self, SheetEdge::Top | SheetEdge::Bottom)
}
#[must_use]
pub fn is_horizontal(self) -> bool {
!self.is_vertical()
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SheetSize {
OneThird,
Half,
TwoThirds,
Ratio(f32),
Pixels(f32),
}
impl SheetSize {
pub const DEFAULT: SheetSize = SheetSize::OneThird;
#[must_use]
pub fn as_ratio(self) -> Option<f32> {
match self {
SheetSize::OneThird => Some(1.0 / 3.0),
SheetSize::Half => Some(0.5),
SheetSize::TwoThirds => Some(2.0 / 3.0),
SheetSize::Ratio(r) => Some(r.clamp(0.0, 1.0)),
SheetSize::Pixels(_) => None,
}
}
#[must_use]
pub fn as_pixels(self) -> Option<f32> {
match self {
SheetSize::Pixels(p) => Some(p),
_ => None,
}
}
}
pub struct Sheet<Node, Message> {
pub content: Node,
pub edge: SheetEdge,
pub size: SheetSize,
_marker: PhantomData<Message>,
}
impl<Node, Message> Sheet<Node, Message> {
pub fn new(content: Node) -> Self {
Self {
content,
edge: SheetEdge::default(),
size: SheetSize::DEFAULT,
_marker: PhantomData,
}
}
#[must_use]
pub fn at(mut self, edge: SheetEdge) -> Self {
self.edge = edge;
self
}
#[must_use]
pub fn with_size(mut self, size: SheetSize) -> Self {
self.size = size;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ratio_resolves_correctly() {
assert_eq!(SheetSize::OneThird.as_ratio(), Some(1.0 / 3.0));
assert_eq!(SheetSize::Half.as_ratio(), Some(0.5));
assert_eq!(SheetSize::TwoThirds.as_ratio(), Some(2.0 / 3.0));
assert_eq!(SheetSize::Ratio(0.25).as_ratio(), Some(0.25));
assert_eq!(SheetSize::Pixels(240.0).as_ratio(), None);
}
#[test]
fn ratio_is_clamped() {
assert_eq!(SheetSize::Ratio(1.5).as_ratio(), Some(1.0));
assert_eq!(SheetSize::Ratio(-0.1).as_ratio(), Some(0.0));
}
#[test]
fn default_sheet_edge_is_bottom() {
assert_eq!(SheetEdge::default(), SheetEdge::Bottom);
}
#[test]
fn vertical_horizontal_partition() {
for edge in [SheetEdge::Top, SheetEdge::Bottom, SheetEdge::Start, SheetEdge::End] {
assert_ne!(edge.is_vertical(), edge.is_horizontal());
}
assert!(SheetEdge::Top.is_vertical());
assert!(SheetEdge::Bottom.is_vertical());
assert!(SheetEdge::Start.is_horizontal());
assert!(SheetEdge::End.is_horizontal());
}
#[test]
fn sheet_builder_overrides() {
let s: Sheet<(), ()> = Sheet::new(())
.at(SheetEdge::Start)
.with_size(SheetSize::Half);
assert_eq!(s.edge, SheetEdge::Start);
assert_eq!(s.size, SheetSize::Half);
}
}