BREAKING: More units of measure work and keyword args (#6291)
* More units of measure work Signed-off-by: Nick Cameron <nrc@ncameron.org> * Update CSG output since engine change --------- Signed-off-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
@ -725,12 +725,7 @@ fn apply_ascription(
|
||||
let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into())
|
||||
.map_err(|e| KclError::Semantic(e.into()))?;
|
||||
|
||||
if let KclValue::Number {
|
||||
ty: NumericType::Unknown,
|
||||
value,
|
||||
meta,
|
||||
} = value
|
||||
{
|
||||
if let KclValue::Number { value, meta, .. } = value {
|
||||
// If the number has unknown units but the user is explicitly specifying them, treat the value as having had it's units erased,
|
||||
// rather than forcing the user to explicitly erase them.
|
||||
KclValue::Number {
|
||||
|
@ -184,62 +184,191 @@ pub struct Plane {
|
||||
|
||||
impl Plane {
|
||||
pub(crate) fn into_plane_data(self) -> PlaneData {
|
||||
if self.origin == Point3d::new(0.0, 0.0, 0.0) {
|
||||
if self.origin.is_zero() {
|
||||
match self {
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 },
|
||||
z_axis: Point3d { x: 0.0, y: 0.0, z: 1.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::XY,
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: -1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::NegXY,
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 0.0, z: 1.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: -1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::XZ,
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 0.0, z: 1.0 },
|
||||
z_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::NegXZ,
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 0.0, z: 1.0 },
|
||||
z_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::YZ,
|
||||
Self {
|
||||
origin: Point3d { x: 0.0, y: 0.0, z: 0.0 },
|
||||
x_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 },
|
||||
y_axis: Point3d { x: 0.0, y: 0.0, z: 1.0 },
|
||||
origin:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
x_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
y_axis:
|
||||
Point3d {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
z_axis:
|
||||
Point3d {
|
||||
x: -1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
},
|
||||
..
|
||||
} => return PlaneData::NegYZ,
|
||||
@ -261,10 +390,10 @@ impl Plane {
|
||||
PlaneData::XY => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 1.0, 0.0),
|
||||
z_axis: Point3d::new(0.0, 0.0, 1.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||
value: PlaneType::XY,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -272,10 +401,10 @@ impl Plane {
|
||||
PlaneData::NegXY => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 1.0, 0.0),
|
||||
z_axis: Point3d::new(0.0, 0.0, -1.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm),
|
||||
value: PlaneType::XY,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -283,10 +412,10 @@ impl Plane {
|
||||
PlaneData::XZ => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0),
|
||||
z_axis: Point3d::new(0.0, -1.0, 0.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
|
||||
value: PlaneType::XZ,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -294,10 +423,10 @@ impl Plane {
|
||||
PlaneData::NegXZ => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(-1.0, 0.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0),
|
||||
z_axis: Point3d::new(0.0, 1.0, 0.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||
value: PlaneType::XZ,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -305,10 +434,10 @@ impl Plane {
|
||||
PlaneData::YZ => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(0.0, 1.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0),
|
||||
z_axis: Point3d::new(1.0, 0.0, 0.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
value: PlaneType::YZ,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -316,10 +445,10 @@ impl Plane {
|
||||
PlaneData::NegYZ => Plane {
|
||||
id,
|
||||
artifact_id: id.into(),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0),
|
||||
x_axis: Point3d::new(0.0, 1.0, 0.0),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0),
|
||||
z_axis: Point3d::new(-1.0, 0.0, 0.0),
|
||||
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
|
||||
x_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||
z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
|
||||
value: PlaneType::YZ,
|
||||
units: exec_state.length_unit(),
|
||||
meta: vec![],
|
||||
@ -512,7 +641,7 @@ pub(crate) enum GetTangentialInfoFromPathsResult {
|
||||
}
|
||||
|
||||
impl GetTangentialInfoFromPathsResult {
|
||||
pub(crate) fn tan_previous_point(&self, last_arc_end: crate::std::utils::Coords2d) -> [f64; 2] {
|
||||
pub(crate) fn tan_previous_point(&self, last_arc_end: [f64; 2]) -> [f64; 2] {
|
||||
match self {
|
||||
GetTangentialInfoFromPathsResult::PreviousPoint(p) => *p,
|
||||
GetTangentialInfoFromPathsResult::Arc { center, ccw, .. } => {
|
||||
@ -567,11 +696,10 @@ impl Sketch {
|
||||
/// where the last path segment ends, and the next path segment will begin.
|
||||
pub(crate) fn current_pen_position(&self) -> Result<Point2d, KclError> {
|
||||
let Some(path) = self.latest_path() else {
|
||||
return Ok(self.start.to.into());
|
||||
return Ok(Point2d::new(self.start.to[0], self.start.to[1], self.start.units));
|
||||
};
|
||||
|
||||
let base = path.get_base();
|
||||
Ok(base.to.into())
|
||||
Ok(path.get_to().into())
|
||||
}
|
||||
|
||||
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
|
||||
@ -624,7 +752,7 @@ pub enum EdgeCut {
|
||||
Fillet {
|
||||
/// The id of the engine command that called this fillet.
|
||||
id: uuid::Uuid,
|
||||
radius: f64,
|
||||
radius: TyF64,
|
||||
/// The engine id of the edge to fillet.
|
||||
#[serde(rename = "edgeId")]
|
||||
edge_id: uuid::Uuid,
|
||||
@ -634,7 +762,7 @@ pub enum EdgeCut {
|
||||
Chamfer {
|
||||
/// The id of the engine command that called this chamfer.
|
||||
id: uuid::Uuid,
|
||||
length: f64,
|
||||
length: TyF64,
|
||||
/// The engine id of the edge to chamfer.
|
||||
#[serde(rename = "edgeId")]
|
||||
edge_id: uuid::Uuid,
|
||||
@ -670,23 +798,16 @@ impl EdgeCut {
|
||||
pub struct Point2d {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
}
|
||||
|
||||
impl From<[f64; 2]> for Point2d {
|
||||
fn from(p: [f64; 2]) -> Self {
|
||||
Self { x: p[0], y: p[1] }
|
||||
}
|
||||
pub units: UnitLen,
|
||||
}
|
||||
|
||||
impl From<[TyF64; 2]> for Point2d {
|
||||
fn from(p: [TyF64; 2]) -> Self {
|
||||
Self { x: p[0].n, y: p[1].n }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[f64; 2]> for Point2d {
|
||||
fn from(p: &[f64; 2]) -> Self {
|
||||
Self { x: p[0], y: p[1] }
|
||||
Self {
|
||||
x: p[0].n,
|
||||
y: p[1].n,
|
||||
units: p[0].ty.expect_length(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,12 +824,14 @@ impl From<Point2d> for Point2D {
|
||||
}
|
||||
|
||||
impl Point2d {
|
||||
pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
|
||||
pub fn scale(self, scalar: f64) -> Self {
|
||||
Self {
|
||||
x: self.x * scalar,
|
||||
y: self.y * scalar,
|
||||
}
|
||||
pub const ZERO: Self = Self {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
};
|
||||
|
||||
pub fn new(x: f64, y: f64, units: UnitLen) -> Self {
|
||||
Self { x, y, units }
|
||||
}
|
||||
}
|
||||
|
||||
@ -718,12 +841,34 @@ pub struct Point3d {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
pub units: UnitLen,
|
||||
}
|
||||
|
||||
impl Point3d {
|
||||
pub const ZERO: Self = Self { x: 0.0, y: 0.0, z: 0.0 };
|
||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
||||
Self { x, y, z }
|
||||
pub const ZERO: Self = Self {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
units: UnitLen::Mm,
|
||||
};
|
||||
|
||||
pub fn new(x: f64, y: f64, z: f64, units: UnitLen) -> Self {
|
||||
Self { x, y, z, units }
|
||||
}
|
||||
|
||||
pub const fn is_zero(&self) -> bool {
|
||||
self.x == 0.0 && self.y == 0.0 && self.z == 0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[TyF64; 3]> for Point3d {
|
||||
fn from(p: [TyF64; 3]) -> Self {
|
||||
Self {
|
||||
x: p[0].n,
|
||||
y: p[1].n,
|
||||
z: p[2].n,
|
||||
units: p[0].ty.expect_length(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,10 +891,12 @@ impl Add for Point3d {
|
||||
type Output = Point3d;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
// TODO should assert that self and rhs the same units or coerce them
|
||||
Point3d {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
z: self.z + rhs.z,
|
||||
units: self.units,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -768,6 +915,7 @@ impl Mul<f64> for Point3d {
|
||||
x: self.x * rhs,
|
||||
y: self.y * rhs,
|
||||
z: self.z * rhs,
|
||||
units: self.units,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -791,6 +939,18 @@ pub struct BasePath {
|
||||
pub geo_meta: GeoMeta,
|
||||
}
|
||||
|
||||
impl BasePath {
|
||||
pub fn get_to(&self) -> [TyF64; 2] {
|
||||
let ty: NumericType = self.units.into();
|
||||
[TyF64::new(self.to[0], ty.clone()), TyF64::new(self.to[1], ty)]
|
||||
}
|
||||
|
||||
pub fn get_from(&self) -> [TyF64; 2] {
|
||||
let ty: NumericType = self.units.into();
|
||||
[TyF64::new(self.from[0], ty.clone()), TyF64::new(self.from[1], ty)]
|
||||
}
|
||||
}
|
||||
|
||||
/// Geometry metadata.
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
@ -990,6 +1150,7 @@ impl Path {
|
||||
let ty: NumericType = self.get_base().units.into();
|
||||
[TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)]
|
||||
}
|
||||
|
||||
/// Where does this path segment end?
|
||||
pub fn get_to(&self) -> [TyF64; 2] {
|
||||
let p = &self.get_base().to;
|
||||
@ -1023,11 +1184,14 @@ impl Path {
|
||||
Self::Circle { radius, .. } => 2.0 * std::f64::consts::PI * radius,
|
||||
Self::CircleThreePoint { .. } => {
|
||||
let circle_center = crate::std::utils::calculate_circle_from_3_points([
|
||||
self.get_base().from.into(),
|
||||
self.get_base().to.into(),
|
||||
self.get_base().to.into(),
|
||||
self.get_base().from,
|
||||
self.get_base().to,
|
||||
self.get_base().to,
|
||||
]);
|
||||
let radius = linear_distance(&[circle_center.center.x, circle_center.center.y], &self.get_base().from);
|
||||
let radius = linear_distance(
|
||||
&[circle_center.center[0], circle_center.center[1]],
|
||||
&self.get_base().from,
|
||||
);
|
||||
2.0 * std::f64::consts::PI * radius
|
||||
}
|
||||
Self::Arc { .. } => {
|
||||
@ -1066,10 +1230,9 @@ impl Path {
|
||||
ccw: *ccw,
|
||||
},
|
||||
Path::ArcThreePoint { p1, p2, p3, .. } => {
|
||||
let circle_center =
|
||||
crate::std::utils::calculate_circle_from_3_points([(*p1).into(), (*p2).into(), (*p3).into()]);
|
||||
let radius = linear_distance(&[circle_center.center.x, circle_center.center.y], p1);
|
||||
let center_point = [circle_center.center.x, circle_center.center.y];
|
||||
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
||||
let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1);
|
||||
let center_point = [circle_center.center[0], circle_center.center[1]];
|
||||
GetTangentialInfoFromPathsResult::Circle {
|
||||
center: center_point,
|
||||
ccw: true,
|
||||
@ -1084,10 +1247,9 @@ impl Path {
|
||||
radius: *radius,
|
||||
},
|
||||
Path::CircleThreePoint { p1, p2, p3, .. } => {
|
||||
let circle_center =
|
||||
crate::std::utils::calculate_circle_from_3_points([(*p1).into(), (*p2).into(), (*p3).into()]);
|
||||
let radius = linear_distance(&[circle_center.center.x, circle_center.center.y], p1);
|
||||
let center_point = [circle_center.center.x, circle_center.center.y];
|
||||
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
||||
let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1);
|
||||
let center_point = [circle_center.center[0], circle_center.center[1]];
|
||||
GetTangentialInfoFromPathsResult::Circle {
|
||||
center: center_point,
|
||||
ccw: true,
|
||||
|
@ -422,23 +422,33 @@ impl KclValue {
|
||||
}
|
||||
|
||||
pub fn as_array(&self) -> Option<&[KclValue]> {
|
||||
if let KclValue::MixedArray { value, meta: _ } = &self {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
match self {
|
||||
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_point2d(&self) -> Option<[f64; 2]> {
|
||||
pub fn as_point2d(&self) -> Option<[TyF64; 2]> {
|
||||
let arr = self.as_array()?;
|
||||
if arr.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
let x = arr[0].as_f64()?;
|
||||
let y = arr[1].as_f64()?;
|
||||
let x = arr[0].as_ty_f64()?;
|
||||
let y = arr[1].as_ty_f64()?;
|
||||
Some([x, y])
|
||||
}
|
||||
|
||||
pub fn as_point3d(&self) -> Option<[TyF64; 3]> {
|
||||
let arr = self.as_array()?;
|
||||
if arr.len() != 3 {
|
||||
return None;
|
||||
}
|
||||
let x = arr[0].as_ty_f64()?;
|
||||
let y = arr[1].as_ty_f64()?;
|
||||
let z = arr[2].as_ty_f64()?;
|
||||
Some([x, y, z])
|
||||
}
|
||||
|
||||
pub fn as_uuid(&self) -> Option<uuid::Uuid> {
|
||||
if let KclValue::Uuid { value, meta: _ } = &self {
|
||||
Some(*value)
|
||||
@ -487,6 +497,7 @@ impl KclValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn as_f64(&self) -> Option<f64> {
|
||||
if let KclValue::Number { value, .. } = &self {
|
||||
Some(*value)
|
||||
|
@ -2050,7 +2050,7 @@ fn foo() {
|
||||
|
||||
solid = sketch |> extrude(length = 10)
|
||||
// tag0 tags a face
|
||||
sketch2 = startSketchOn(solid, tag0)
|
||||
sketch2 = startSketchOn(solid, face = tag0)
|
||||
|> startProfileAt([0,0], %)
|
||||
|> line(end = [0, 1])
|
||||
|> line(end = [1, 0])
|
||||
|
@ -62,21 +62,57 @@ impl RuntimeType {
|
||||
RuntimeType::Primitive(PrimitiveType::Solid)
|
||||
}
|
||||
|
||||
pub fn plane() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Plane)
|
||||
}
|
||||
|
||||
pub fn string() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::String)
|
||||
}
|
||||
|
||||
pub fn imported() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::ImportedGeometry)
|
||||
}
|
||||
|
||||
/// `[number; 2]`
|
||||
pub fn point2d() -> Self {
|
||||
RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(2))
|
||||
RuntimeType::Array(Box::new(RuntimeType::length()), ArrayLen::Known(2))
|
||||
}
|
||||
|
||||
/// `[number; 3]`
|
||||
pub fn point3d() -> Self {
|
||||
RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(3))
|
||||
RuntimeType::Array(Box::new(RuntimeType::length()), ArrayLen::Known(3))
|
||||
}
|
||||
|
||||
pub fn number_any() -> Self {
|
||||
pub fn length() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Length(
|
||||
UnitLen::Unknown,
|
||||
))))
|
||||
}
|
||||
|
||||
pub fn angle() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
|
||||
UnitAngle::Unknown,
|
||||
))))
|
||||
}
|
||||
|
||||
pub fn radians() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
|
||||
UnitAngle::Radians,
|
||||
))))
|
||||
}
|
||||
|
||||
pub fn degrees() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
|
||||
UnitAngle::Degrees,
|
||||
))))
|
||||
}
|
||||
|
||||
pub fn count() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Count)))
|
||||
}
|
||||
|
||||
pub fn num_any() -> Self {
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any))
|
||||
}
|
||||
|
||||
@ -397,8 +433,8 @@ impl NumericType {
|
||||
(Default { .. }, Default { .. }) | (_, Unknown) | (Unknown, _) => (a.n, b.n, Unknown),
|
||||
|
||||
// Known types and compatible, but needs adjustment.
|
||||
(t @ Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => (a.n, l2.adjust_to(b.n, l1), t),
|
||||
(t @ Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => (a.n, a2.adjust_to(b.n, a1), t),
|
||||
(t @ Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => (a.n, l2.adjust_to(b.n, l1).0, t),
|
||||
(t @ Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => (a.n, a2.adjust_to(b.n, a1).0, t),
|
||||
|
||||
// Known but incompatible.
|
||||
(Known(_), Known(_)) => (a.n, b.n, Unknown),
|
||||
@ -408,11 +444,11 @@ impl NumericType {
|
||||
(a.n, b.n, Known(UnitType::Count))
|
||||
}
|
||||
|
||||
(t @ Known(UnitType::Length(l1)), Default { len: l2, .. }) => (a.n, l2.adjust_to(b.n, l1), t),
|
||||
(Default { len: l1, .. }, t @ Known(UnitType::Length(l2))) => (l1.adjust_to(a.n, l2), b.n, t),
|
||||
(t @ Known(UnitType::Length(l1)), Default { len: l2, .. }) => (a.n, l2.adjust_to(b.n, l1).0, t),
|
||||
(Default { len: l1, .. }, t @ Known(UnitType::Length(l2))) => (l1.adjust_to(a.n, l2).0, b.n, t),
|
||||
|
||||
(t @ Known(UnitType::Angle(a1)), Default { angle: a2, .. }) => (a.n, a2.adjust_to(b.n, a1), t),
|
||||
(Default { angle: a1, .. }, t @ Known(UnitType::Angle(a2))) => (a1.adjust_to(a.n, a2), b.n, t),
|
||||
(t @ Known(UnitType::Angle(a1)), Default { angle: a2, .. }) => (a.n, a2.adjust_to(b.n, a1).0, t),
|
||||
(Default { angle: a1, .. }, t @ Known(UnitType::Angle(a2))) => (a1.adjust_to(a.n, a2).0, b.n, t),
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,7 +458,7 @@ impl NumericType {
|
||||
let mut result = input.iter().map(|t| t.n).collect();
|
||||
|
||||
let mut ty = Any;
|
||||
// Invariant mismatch is true => ty is Known
|
||||
// Invariant mismatch is true => ty is fully known
|
||||
let mut mismatch = false;
|
||||
for i in input {
|
||||
if i.ty == Any || ty == i.ty {
|
||||
@ -478,10 +514,10 @@ impl NumericType {
|
||||
.zip(input)
|
||||
.map(|(n, i)| match (&ty, &i.ty) {
|
||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2)) | Default { len: l2, .. }) => {
|
||||
l2.adjust_to(n, *l1)
|
||||
l2.adjust_to(n, *l1).0
|
||||
}
|
||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2)) | Default { angle: a2, .. }) => {
|
||||
a2.adjust_to(n, *a1)
|
||||
a2.adjust_to(n, *a1).0
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
@ -495,8 +531,10 @@ impl NumericType {
|
||||
use NumericType::*;
|
||||
match (a.ty, b.ty) {
|
||||
(at @ Default { .. }, bt @ Default { .. }) if at != bt => (a.n, b.n, Unknown),
|
||||
(Known(UnitType::Count) | Default { .. }, bt) => (a.n, b.n, bt),
|
||||
(at, Known(UnitType::Count) | Default { .. }) => (a.n, b.n, at),
|
||||
(Known(UnitType::Count), bt) => (a.n, b.n, bt),
|
||||
(at, Known(UnitType::Count)) => (a.n, b.n, at),
|
||||
(Default { .. }, bt) => (a.n, b.n, bt),
|
||||
(at, Default { .. }) => (a.n, b.n, at),
|
||||
(Any, Any) => (a.n, b.n, Any),
|
||||
_ => (a.n, b.n, Unknown),
|
||||
}
|
||||
@ -506,21 +544,23 @@ impl NumericType {
|
||||
pub fn combine_div(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
||||
use NumericType::*;
|
||||
match (a.ty, b.ty) {
|
||||
(at @ Default { .. }, bt @ Default { .. }) if at == bt => (a.n, b.n, at),
|
||||
(at, bt) if at == bt => (a.n, b.n, Known(UnitType::Count)),
|
||||
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
|
||||
(at, Known(UnitType::Count) | Default { .. } | Any) => (a.n, b.n, at),
|
||||
(at, Known(UnitType::Count) | Any) => (a.n, b.n, at),
|
||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => {
|
||||
(a.n, l2.adjust_to(b.n, l1), Known(UnitType::Count))
|
||||
(a.n, l2.adjust_to(b.n, l1).0, Known(UnitType::Count))
|
||||
}
|
||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => {
|
||||
(a.n, a2.adjust_to(b.n, a1), Known(UnitType::Count))
|
||||
(a.n, a2.adjust_to(b.n, a1).0, Known(UnitType::Count))
|
||||
}
|
||||
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
|
||||
(l1.adjust_to(a.n, l2), b.n, Known(UnitType::Count))
|
||||
(l1.adjust_to(a.n, l2).0, b.n, Known(UnitType::Count))
|
||||
}
|
||||
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
|
||||
(a1.adjust_to(a.n, a2), b.n, Known(UnitType::Count))
|
||||
(a1.adjust_to(a.n, a2).0, b.n, Known(UnitType::Count))
|
||||
}
|
||||
(Known(UnitType::Count), _) => (a.n, b.n, Known(UnitType::Count)),
|
||||
_ => (a.n, b.n, Unknown),
|
||||
}
|
||||
}
|
||||
@ -532,6 +572,8 @@ impl NumericType {
|
||||
angle: settings.default_angle_units,
|
||||
},
|
||||
NumericSuffix::Count => NumericType::Known(UnitType::Count),
|
||||
NumericSuffix::Length => NumericType::Known(UnitType::Length(UnitLen::Unknown)),
|
||||
NumericSuffix::Angle => NumericType::Known(UnitType::Angle(UnitAngle::Unknown)),
|
||||
NumericSuffix::Mm => NumericType::Known(UnitType::Length(UnitLen::Mm)),
|
||||
NumericSuffix::Cm => NumericType::Known(UnitType::Length(UnitLen::Cm)),
|
||||
NumericSuffix::M => NumericType::Known(UnitType::Length(UnitLen::M)),
|
||||
@ -549,6 +591,14 @@ impl NumericType {
|
||||
match (self, other) {
|
||||
(_, Any) => true,
|
||||
(a, b) if a == b => true,
|
||||
(
|
||||
NumericType::Known(UnitType::Length(_)) | NumericType::Default { .. },
|
||||
NumericType::Known(UnitType::Length(UnitLen::Unknown)),
|
||||
)
|
||||
| (
|
||||
NumericType::Known(UnitType::Angle(_)) | NumericType::Default { .. },
|
||||
NumericType::Known(UnitType::Angle(UnitAngle::Unknown)),
|
||||
) => true,
|
||||
(Unknown, _) | (_, Unknown) => false,
|
||||
(_, _) => false,
|
||||
}
|
||||
@ -599,16 +649,22 @@ impl NumericType {
|
||||
}),
|
||||
|
||||
// Known types and compatible, but needs adjustment.
|
||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => Ok(KclValue::Number {
|
||||
value: l1.adjust_to(*value, *l2),
|
||||
ty: self.clone(),
|
||||
meta: meta.clone(),
|
||||
}),
|
||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => Ok(KclValue::Number {
|
||||
value: a1.adjust_to(*value, *a2),
|
||||
ty: self.clone(),
|
||||
meta: meta.clone(),
|
||||
}),
|
||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => {
|
||||
let (value, ty) = l1.adjust_to(*value, *l2);
|
||||
Ok(KclValue::Number {
|
||||
value,
|
||||
ty: Known(UnitType::Length(ty)),
|
||||
meta: meta.clone(),
|
||||
})
|
||||
}
|
||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => {
|
||||
let (value, ty) = a1.adjust_to(*value, *a2);
|
||||
Ok(KclValue::Number {
|
||||
value,
|
||||
ty: Known(UnitType::Angle(ty)),
|
||||
meta: meta.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
// Known but incompatible.
|
||||
(Known(_), Known(_)) => Err(val.into()),
|
||||
@ -623,22 +679,42 @@ impl NumericType {
|
||||
}
|
||||
|
||||
(Known(UnitType::Length(l1)), Default { len: l2, .. })
|
||||
| (Default { len: l1, .. }, Known(UnitType::Length(l2))) => Ok(KclValue::Number {
|
||||
value: l1.adjust_to(*value, *l2),
|
||||
ty: Known(UnitType::Length(*l2)),
|
||||
meta: meta.clone(),
|
||||
}),
|
||||
| (Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
|
||||
let (value, ty) = l1.adjust_to(*value, *l2);
|
||||
Ok(KclValue::Number {
|
||||
value,
|
||||
ty: Known(UnitType::Length(ty)),
|
||||
meta: meta.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
(Known(UnitType::Angle(a1)), Default { angle: a2, .. })
|
||||
| (Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => Ok(KclValue::Number {
|
||||
value: a1.adjust_to(*value, *a2),
|
||||
ty: Known(UnitType::Angle(*a2)),
|
||||
meta: meta.clone(),
|
||||
}),
|
||||
| (Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
|
||||
let (value, ty) = a1.adjust_to(*value, *a2);
|
||||
Ok(KclValue::Number {
|
||||
value,
|
||||
ty: Known(UnitType::Angle(ty)),
|
||||
meta: meta.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
(_, _) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_length(&self) -> UnitLen {
|
||||
match self {
|
||||
Self::Known(UnitType::Length(len)) | Self::Default { len, .. } => *len,
|
||||
_ => unreachable!("Found {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_length(&self) -> Option<UnitLen> {
|
||||
match self {
|
||||
Self::Known(UnitType::Length(len)) | Self::Default { len, .. } => Some(*len),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NumericType> for RuntimeType {
|
||||
@ -691,15 +767,21 @@ pub enum UnitLen {
|
||||
Inches,
|
||||
Feet,
|
||||
Yards,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl UnitLen {
|
||||
fn adjust_to(self, value: f64, to: UnitLen) -> f64 {
|
||||
fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
|
||||
use UnitLen::*;
|
||||
|
||||
if !*CHECK_NUMERIC_TYPES || self == to {
|
||||
return value;
|
||||
return (value, to);
|
||||
}
|
||||
|
||||
if to == Unknown {
|
||||
return (value, self);
|
||||
}
|
||||
|
||||
use UnitLen::*;
|
||||
let (base, base_unit) = match self {
|
||||
Mm => (value, Mm),
|
||||
Cm => (value * 10.0, Mm),
|
||||
@ -707,6 +789,7 @@ impl UnitLen {
|
||||
Inches => (value, Inches),
|
||||
Feet => (value * 12.0, Inches),
|
||||
Yards => (value * 36.0, Inches),
|
||||
Unknown => unreachable!(),
|
||||
};
|
||||
let (base, base_unit) = match (base_unit, to) {
|
||||
(Mm, Inches) | (Mm, Feet) | (Mm, Yards) => (base / 25.4, Inches),
|
||||
@ -714,7 +797,7 @@ impl UnitLen {
|
||||
_ => (base, base_unit),
|
||||
};
|
||||
|
||||
match (base_unit, to) {
|
||||
let value = match (base_unit, to) {
|
||||
(Mm, Mm) => base,
|
||||
(Mm, Cm) => base / 10.0,
|
||||
(Mm, M) => base / 1000.0,
|
||||
@ -722,7 +805,9 @@ impl UnitLen {
|
||||
(Inches, Feet) => base / 12.0,
|
||||
(Inches, Yards) => base / 36.0,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
(value, to)
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,6 +820,7 @@ impl std::fmt::Display for UnitLen {
|
||||
UnitLen::Inches => write!(f, "in"),
|
||||
UnitLen::Feet => write!(f, "ft"),
|
||||
UnitLen::Yards => write!(f, "yd"),
|
||||
UnitLen::Unknown => write!(f, "Length"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -777,6 +863,7 @@ impl From<UnitLen> for crate::UnitLength {
|
||||
UnitLen::M => crate::UnitLength::M,
|
||||
UnitLen::Mm => crate::UnitLength::Mm,
|
||||
UnitLen::Yards => crate::UnitLength::Yd,
|
||||
UnitLen::Unknown => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -790,6 +877,7 @@ impl From<UnitLen> for kittycad_modeling_cmds::units::UnitLength {
|
||||
UnitLen::M => kittycad_modeling_cmds::units::UnitLength::Meters,
|
||||
UnitLen::Mm => kittycad_modeling_cmds::units::UnitLength::Millimeters,
|
||||
UnitLen::Yards => kittycad_modeling_cmds::units::UnitLength::Yards,
|
||||
UnitLen::Unknown => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -802,24 +890,32 @@ pub enum UnitAngle {
|
||||
#[default]
|
||||
Degrees,
|
||||
Radians,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl UnitAngle {
|
||||
fn adjust_to(self, value: f64, to: UnitAngle) -> f64 {
|
||||
fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
|
||||
use std::f64::consts::PI;
|
||||
|
||||
use UnitAngle::*;
|
||||
|
||||
if !*CHECK_NUMERIC_TYPES {
|
||||
return value;
|
||||
return (value, to);
|
||||
}
|
||||
|
||||
match (self, to) {
|
||||
if to == Unknown {
|
||||
return (value, self);
|
||||
}
|
||||
|
||||
let value = match (self, to) {
|
||||
(Degrees, Degrees) => value,
|
||||
(Degrees, Radians) => (value / 180.0) * PI,
|
||||
(Radians, Degrees) => 180.0 * value / PI,
|
||||
(Radians, Radians) => value,
|
||||
}
|
||||
(Unknown, _) | (_, Unknown) => unreachable!(),
|
||||
};
|
||||
|
||||
(value, to)
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,6 +924,7 @@ impl std::fmt::Display for UnitAngle {
|
||||
match self {
|
||||
UnitAngle::Degrees => write!(f, "deg"),
|
||||
UnitAngle::Radians => write!(f, "rad"),
|
||||
UnitAngle::Unknown => write!(f, "Angle"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -920,6 +1017,14 @@ impl KclValue {
|
||||
_ => Err(self.into()),
|
||||
},
|
||||
PrimitiveType::Plane => match value {
|
||||
KclValue::String { value: s, .. }
|
||||
if [
|
||||
"xy", "xz", "yz", "-xy", "-xz", "-yz", "XY", "XZ", "YZ", "-XY", "-XZ", "-YZ",
|
||||
]
|
||||
.contains(&&**s) =>
|
||||
{
|
||||
Ok(value.clone())
|
||||
}
|
||||
KclValue::Plane { .. } => Ok(value.clone()),
|
||||
KclValue::Object { value, meta } => {
|
||||
let origin = value
|
||||
@ -985,10 +1090,10 @@ impl KclValue {
|
||||
}
|
||||
|
||||
let origin = values.get("origin").ok_or(self.into()).and_then(|p| {
|
||||
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
|
||||
p.coerce_to_array_type(&RuntimeType::length(), ArrayLen::Known(2), exec_state, true)
|
||||
})?;
|
||||
let direction = values.get("direction").ok_or(self.into()).and_then(|p| {
|
||||
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
|
||||
p.coerce_to_array_type(&RuntimeType::length(), ArrayLen::Known(2), exec_state, true)
|
||||
})?;
|
||||
|
||||
Ok(KclValue::Object {
|
||||
@ -1013,10 +1118,10 @@ impl KclValue {
|
||||
}
|
||||
|
||||
let origin = values.get("origin").ok_or(self.into()).and_then(|p| {
|
||||
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
|
||||
p.coerce_to_array_type(&RuntimeType::length(), ArrayLen::Known(3), exec_state, true)
|
||||
})?;
|
||||
let direction = values.get("direction").ok_or(self.into()).and_then(|p| {
|
||||
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
|
||||
p.coerce_to_array_type(&RuntimeType::length(), ArrayLen::Known(3), exec_state, true)
|
||||
})?;
|
||||
|
||||
Ok(KclValue::Object {
|
||||
@ -1980,12 +2085,12 @@ u = min(3rad, 4in)
|
||||
assert_value_and_type("j", &result, 20.0, NumericType::default());
|
||||
assert_value_and_type("k", &result, 18.0, NumericType::Unknown);
|
||||
|
||||
assert_value_and_type("l", &result, 0.0, NumericType::count());
|
||||
assert_value_and_type("l", &result, 0.0, NumericType::default());
|
||||
assert_value_and_type("m", &result, 2.0, NumericType::count());
|
||||
if *CHECK_NUMERIC_TYPES {
|
||||
assert_value_and_type("n", &result, 127.0, NumericType::count());
|
||||
}
|
||||
assert_value_and_type("o", &result, 1.0, NumericType::mm());
|
||||
assert_value_and_type("o", &result, 1.0, NumericType::Unknown);
|
||||
assert_value_and_type("p", &result, 1.0, NumericType::count());
|
||||
assert_value_and_type("q", &result, 2.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
|
||||
|
||||
|
Reference in New Issue
Block a user