Feature fields: a type for each role (Expr, BodyName, FacePick…) (#1273)

Thanks @jijinbei.
This commit is contained in:
JIJINBEI authored and GitHub committed 2026-10-16 00:28:12 -04:00
1 parent 3333f8a62b
commit 44968dbfe6
59 files changed
+1505 -1043

No files matched your search

+88
View File
@@ -15,6 +15,94 @@ const MAX_LEN: usize = 4096;
const MAX_DEPTH: usize = 64;
const MAX_ARGS: usize = 64;
/// An expression a feature holds, as the user wrote it (`2 * width + 5 mm`): kept as text and
/// evaluated with the design's parameters. It is saved as a plain string, and reads as one
/// (`&expr` is a `&str`); it changes only as a whole (`*expr = new.into()`).
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct Expr(String);
impl Expr {
pub fn new(s: impl Into<String>) -> Self {
Expr(s.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn into_string(self) -> String {
self.0
}
}
impl std::ops::Deref for Expr {
type Target = str;
fn deref(&self) -> &str {
&self.0
}
}
impl AsRef<str> for Expr {
fn as_ref(&self) -> &str {
&self.0
}
}
impl From<String> for Expr {
fn from(s: String) -> Self {
Expr(s)
}
}
impl From<&str> for Expr {
fn from(s: &str) -> Self {
Expr(s.to_string())
}
}
impl From<&String> for Expr {
fn from(s: &String) -> Self {
Expr(s.clone())
}
}
impl From<Expr> for String {
fn from(e: Expr) -> Self {
e.0
}
}
impl std::fmt::Display for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
impl PartialEq<str> for Expr {
fn eq(&self, other: &str) -> bool {
self.0 == other
}
}
impl PartialEq<&str> for Expr {
fn eq(&self, other: &&str) -> bool {
self.0 == *other
}
}
impl PartialEq<Expr> for String {
fn eq(&self, other: &Expr) -> bool {
*self == other.0
}
}
impl PartialEq<String> for Expr {
fn eq(&self, other: &String) -> bool {
&self.0 == other
}
}
/// What an expression must evaluate to.
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]