build(deps): use kasuari instead of cassowary (#1758)

[Kasuari](https://github.com/ratatui/kasuari) is a maintained fork of Cassowary.
This commit is contained in:
Josh McKinney 2025-04-04 00:03:39 -07:00 committed by GitHub
parent ebe10cd81f
commit 3d5b250e74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 76 additions and 72 deletions

56
Cargo.lock generated
View File

@ -354,12 +354,6 @@ dependencies = [
"thiserror 2.0.12",
]
[[package]]
name = "cassowary"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cast"
version = "0.3.0"
@ -903,6 +897,16 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "env_logger"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"log",
"regex",
]
[[package]]
name = "equivalent"
version = "1.0.2"
@ -1651,6 +1655,19 @@ dependencies = [
"simple_asn1",
]
[[package]]
name = "kasuari"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf4d16f344910446711b7e223a5351073ab8c93dc5c84c5be2c0965346316b1"
dependencies = [
"hashbrown",
"quickcheck",
"quickcheck_macros",
"rstest",
"thiserror 2.0.12",
]
[[package]]
name = "lab"
version = "0.11.0"
@ -2325,6 +2342,28 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quickcheck"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
dependencies = [
"env_logger",
"log",
"rand 0.8.5",
]
[[package]]
name = "quickcheck_macros"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b22a693222d716a9587786f37ac3f6b4faedb5b80c23914e7303ff5a1d8016e9"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "quote"
version = "1.0.39"
@ -2436,6 +2475,9 @@ name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.15",
]
[[package]]
name = "rand_core"
@ -2548,12 +2590,12 @@ version = "0.1.0-alpha.3"
dependencies = [
"anstyle",
"bitflags 2.9.0",
"cassowary",
"compact_str",
"document-features",
"hashbrown",
"indoc",
"itertools 0.13.0",
"kasuari",
"lru",
"palette",
"pretty_assertions",

View File

@ -45,12 +45,12 @@ serde = ["dep:serde", "bitflags/serde", "compact_str/serde"]
[dependencies]
anstyle = { version = "1", optional = true }
bitflags = "2.3"
cassowary = "0.3"
compact_str = "0.8.0"
document-features = { workspace = true, optional = true }
hashbrown = "0.15.2"
indoc.workspace = true
itertools.workspace = true
kasuari = "0.4.0"
lru = "0.12.0"
palette = { version = "0.7.6", optional = true }
serde = { workspace = true, optional = true }

View File

@ -3,11 +3,10 @@ use core::cell::RefCell;
use core::iter;
use core::num::NonZeroUsize;
use cassowary::strength::REQUIRED;
use cassowary::WeightedRelation::{EQ, GE, LE};
use cassowary::{AddConstraintError, Expression, Solver, Variable};
use hashbrown::HashMap;
use itertools::Itertools;
use kasuari::WeightedRelation::{EQ, GE, LE};
use kasuari::{AddConstraintError, Expression, Solver, Strength, Variable};
use lru::LruCache;
use self::strengths::{
@ -769,8 +768,8 @@ fn configure_area(
area_start: f64,
area_end: f64,
) -> Result<(), AddConstraintError> {
solver.add_constraint(area.start | EQ(REQUIRED) | area_start)?;
solver.add_constraint(area.end | EQ(REQUIRED) | area_end)?;
solver.add_constraint(area.start | EQ(Strength::REQUIRED) | area_start)?;
solver.add_constraint(area.end | EQ(Strength::REQUIRED) | area_end)?;
Ok(())
}
@ -781,8 +780,8 @@ fn configure_variable_in_area_constraints(
) -> Result<(), AddConstraintError> {
// all variables are in the range [area.start, area.end]
for &variable in variables {
solver.add_constraint(variable | GE(REQUIRED) | area.start)?;
solver.add_constraint(variable | LE(REQUIRED) | area.end)?;
solver.add_constraint(variable | GE(Strength::REQUIRED) | area.start)?;
solver.add_constraint(variable | LE(Strength::REQUIRED) | area.end)?;
}
Ok(())
@ -802,7 +801,7 @@ fn configure_variable_constraints(
// └v0 └v1 └v2 └v3 └v4 └v5 └v6 └v7
for (&left, &right) in variables.iter().skip(1).tuples() {
solver.add_constraint(left | LE(REQUIRED) | right)?;
solver.add_constraint(left | LE(Strength::REQUIRED) | right)?;
}
Ok(())
}
@ -1048,24 +1047,24 @@ impl Element {
self.end - self.start
}
fn has_max_size(&self, size: u16, strength: f64) -> cassowary::Constraint {
fn has_max_size(&self, size: u16, strength: Strength) -> kasuari::Constraint {
self.size() | LE(strength) | (f64::from(size) * FLOAT_PRECISION_MULTIPLIER)
}
fn has_min_size(&self, size: i16, strength: f64) -> cassowary::Constraint {
fn has_min_size(&self, size: i16, strength: Strength) -> kasuari::Constraint {
self.size() | GE(strength) | (f64::from(size) * FLOAT_PRECISION_MULTIPLIER)
}
fn has_int_size(&self, size: u16, strength: f64) -> cassowary::Constraint {
fn has_int_size(&self, size: u16, strength: Strength) -> kasuari::Constraint {
self.size() | EQ(strength) | (f64::from(size) * FLOAT_PRECISION_MULTIPLIER)
}
fn has_size<E: Into<Expression>>(&self, size: E, strength: f64) -> cassowary::Constraint {
fn has_size<E: Into<Expression>>(&self, size: E, strength: Strength) -> kasuari::Constraint {
self.size() | EQ(strength) | size.into()
}
fn is_empty(&self) -> cassowary::Constraint {
self.size() | EQ(REQUIRED - 1.0) | 0.0
fn is_empty(&self) -> kasuari::Constraint {
self.size() | EQ(Strength::REQUIRED - Strength::WEAK) | 0.0
}
}
@ -1084,91 +1083,91 @@ impl From<&Element> for Expression {
}
mod strengths {
use cassowary::strength::{MEDIUM, REQUIRED, STRONG, WEAK};
use kasuari::Strength;
/// The strength to apply to Spacers to ensure that their sizes are equal.
///
/// ┌ ┐┌───┐┌ ┐┌───┐┌ ┐
/// ==x │ │ ==x │ │ ==x
/// └ ┘└───┘└ ┘└───┘└ ┘
pub const SPACER_SIZE_EQ: f64 = REQUIRED / 10.0;
pub const SPACER_SIZE_EQ: Strength = Strength::REQUIRED.div_f64(10.0);
/// The strength to apply to Min inequality constraints.
///
/// ┌────────┐
/// │Min(>=x)│
/// └────────┘
pub const MIN_SIZE_GE: f64 = STRONG * 100.0;
pub const MIN_SIZE_GE: Strength = Strength::STRONG.mul_f64(100.0);
/// The strength to apply to Max inequality constraints.
///
/// ┌────────┐
/// │Max(<=x)│
/// └────────┘
pub const MAX_SIZE_LE: f64 = STRONG * 100.0;
pub const MAX_SIZE_LE: Strength = Strength::STRONG.mul_f64(100.0);
/// The strength to apply to Length constraints.
///
/// ┌───────────┐
/// │Length(==x)│
/// └───────────┘
pub const LENGTH_SIZE_EQ: f64 = STRONG * 10.0;
pub const LENGTH_SIZE_EQ: Strength = Strength::STRONG.mul_f64(10.0);
/// The strength to apply to Percentage constraints.
///
/// ┌───────────────┐
/// │Percentage(==x)│
/// └───────────────┘
pub const PERCENTAGE_SIZE_EQ: f64 = STRONG;
pub const PERCENTAGE_SIZE_EQ: Strength = Strength::STRONG;
/// The strength to apply to Ratio constraints.
///
/// ┌────────────┐
/// │Ratio(==x,y)│
/// └────────────┘
pub const RATIO_SIZE_EQ: f64 = STRONG / 10.0;
pub const RATIO_SIZE_EQ: Strength = Strength::STRONG.div_f64(10.0);
/// The strength to apply to Min equality constraints.
///
/// ┌────────┐
/// │Min(==x)│
/// └────────┘
pub const MIN_SIZE_EQ: f64 = MEDIUM * 10.0;
pub const MIN_SIZE_EQ: Strength = Strength::MEDIUM.mul_f64(10.0);
/// The strength to apply to Max equality constraints.
///
/// ┌────────┐
/// │Max(==x)│
/// └────────┘
pub const MAX_SIZE_EQ: f64 = MEDIUM * 10.0;
pub const MAX_SIZE_EQ: Strength = Strength::MEDIUM.mul_f64(10.0);
/// The strength to apply to Fill growing constraints.
///
/// ┌─────────────────────┐
/// │<= Fill(x) =>│
/// └─────────────────────┘
pub const FILL_GROW: f64 = MEDIUM;
pub const FILL_GROW: Strength = Strength::MEDIUM;
/// The strength to apply to growing constraints.
///
/// ┌────────────┐
/// │<= Min(x) =>│
/// └────────────┘
pub const GROW: f64 = MEDIUM / 10.0;
pub const GROW: Strength = Strength::MEDIUM.div_f64(10.0);
/// The strength to apply to Spacer growing constraints.
///
/// ┌ ┐
/// <= x =>
/// └ ┘
pub const SPACE_GROW: f64 = WEAK * 10.0;
pub const SPACE_GROW: Strength = Strength::WEAK.mul_f64(10.0);
/// The strength to apply to growing the size of all segments equally.
///
/// ┌───────┐
/// │<= x =>│
/// └───────┘
pub const ALL_SEGMENT_GROW: f64 = WEAK;
pub const ALL_SEGMENT_GROW: Strength = Strength::WEAK;
}
#[cfg(test)]
@ -2675,41 +2674,4 @@ mod tests {
assert_eq!(result, expected);
}
}
#[test]
fn test_solver() {
use super::*;
let mut solver = Solver::new();
let x = Variable::new();
let y = Variable::new();
solver.add_constraint((x + y) | EQ(4.0) | 5.0).unwrap();
solver.add_constraint(x | EQ(1.0) | 2.0).unwrap();
for _ in 0..5 {
solver.add_constraint(y | EQ(1.0) | 2.0).unwrap();
}
let changes: HashMap<Variable, f64> = solver.fetch_changes().iter().copied().collect();
let x = changes.get(&x).unwrap_or(&0.0).round() as u16;
let y = changes.get(&y).unwrap_or(&0.0).round() as u16;
assert_eq!(x, 3);
assert_eq!(y, 2);
let mut solver = Solver::new();
let x = Variable::new();
let y = Variable::new();
solver.add_constraint((x + y) | EQ(4.0) | 5.0).unwrap();
solver.add_constraint(y | EQ(1.0) | 2.0).unwrap();
for _ in 0..5 {
solver.add_constraint(x | EQ(1.0) | 2.0).unwrap();
}
let changes: HashMap<Variable, f64> = solver.fetch_changes().iter().copied().collect();
let x = changes.get(&x).unwrap_or(&0.0).round() as u16;
let y = changes.get(&y).unwrap_or(&0.0).round() as u16;
assert_eq!(x, 2);
assert_eq!(y, 3);
}
}