Another project
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.9 kB View raw
1use serde::{Deserialize, Serialize}; 2 3use crate::{EdgeLabel, FaceLabel, Plane3, Point3, Result, TypesError, UnitVec3, VertexLabel}; 4 5#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 6#[serde(deny_unknown_fields)] 7pub struct FaceFingerprint { 8 pub plane: Plane3, 9 pub centroid: Point3, 10} 11 12impl core::fmt::Display for FaceFingerprint { 13 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 14 write!(f, "face@{}", self.centroid) 15 } 16} 17 18#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 19#[serde(deny_unknown_fields)] 20pub struct EdgeFingerprint { 21 pub sample: Point3, 22 pub direction: UnitVec3, 23} 24 25impl core::fmt::Display for EdgeFingerprint { 26 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 27 write!(f, "edge@{}", self.sample) 28 } 29} 30 31#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 32#[serde(deny_unknown_fields)] 33pub struct VertexFingerprint { 34 pub point: Point3, 35} 36 37impl core::fmt::Display for VertexFingerprint { 38 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 39 write!(f, "vertex@{}", self.point) 40 } 41} 42 43#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 44pub enum EntityFingerprint { 45 Face(FaceFingerprint), 46 Edge(EdgeFingerprint), 47 Vertex(VertexFingerprint), 48} 49 50impl core::fmt::Display for EntityFingerprint { 51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 52 match self { 53 Self::Face(g) => g.fmt(f), 54 Self::Edge(g) => g.fmt(f), 55 Self::Vertex(g) => g.fmt(f), 56 } 57 } 58} 59 60#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 61pub enum EntityRef { 62 Face(FaceLabel, FaceFingerprint), 63 Edge(EdgeLabel, EdgeFingerprint), 64 Vertex(VertexLabel, VertexFingerprint), 65} 66 67impl EntityRef { 68 #[must_use] 69 pub fn fingerprint(self) -> EntityFingerprint { 70 match self { 71 Self::Face(_, g) => EntityFingerprint::Face(g), 72 Self::Edge(_, g) => EntityFingerprint::Edge(g), 73 Self::Vertex(_, g) => EntityFingerprint::Vertex(g), 74 } 75 } 76} 77 78impl core::fmt::Display for EntityRef { 79 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 80 match self { 81 Self::Face(label, _) => label.fmt(f), 82 Self::Edge(label, _) => label.fmt(f), 83 Self::Vertex(label, _) => label.fmt(f), 84 } 85 } 86} 87 88#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 89#[serde(deny_unknown_fields)] 90pub struct FaceRef { 91 pub label: FaceLabel, 92 pub fingerprint: FaceFingerprint, 93} 94 95impl FaceRef { 96 #[must_use] 97 pub const fn new(label: FaceLabel, fingerprint: FaceFingerprint) -> Self { 98 Self { label, fingerprint } 99 } 100 101 #[must_use] 102 pub const fn entity_ref(self) -> EntityRef { 103 EntityRef::Face(self.label, self.fingerprint) 104 } 105} 106 107impl core::fmt::Display for FaceRef { 108 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 109 self.label.fmt(f) 110 } 111} 112 113#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] 114#[serde(try_from = "f64", into = "f64")] 115pub struct MatchScore(f64); 116 117impl MatchScore { 118 pub fn new(value: f64) -> Result<Self> { 119 if value.is_finite() && (0.0..=1.0).contains(&value) { 120 Ok(Self(value)) 121 } else { 122 Err(TypesError::MatchScoreOutOfRange(value)) 123 } 124 } 125 126 #[must_use] 127 pub const fn value(self) -> f64 { 128 self.0 129 } 130} 131 132impl TryFrom<f64> for MatchScore { 133 type Error = TypesError; 134 fn try_from(value: f64) -> Result<Self> { 135 Self::new(value) 136 } 137} 138 139impl From<MatchScore> for f64 { 140 fn from(score: MatchScore) -> Self { 141 score.0 142 } 143} 144 145impl core::fmt::Display for MatchScore { 146 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 147 write!(f, "score={}", self.0) 148 } 149} 150 151#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 152#[serde(deny_unknown_fields)] 153pub enum Resolution<Id> { 154 Resolved(Id), 155 Repaired { id: Id, score: MatchScore }, 156 Dangling { last_known: EntityRef }, 157} 158 159impl<Id> Resolution<Id> { 160 #[must_use] 161 pub fn id(self) -> Option<Id> { 162 match self { 163 Self::Resolved(id) | Self::Repaired { id, .. } => Some(id), 164 Self::Dangling { .. } => None, 165 } 166 } 167 168 #[must_use] 169 pub fn map<U>(self, f: impl FnOnce(Id) -> U) -> Resolution<U> { 170 match self { 171 Self::Resolved(id) => Resolution::Resolved(f(id)), 172 Self::Repaired { id, score } => Resolution::Repaired { id: f(id), score }, 173 Self::Dangling { last_known } => Resolution::Dangling { last_known }, 174 } 175 } 176 177 #[must_use] 178 pub const fn is_dangling(&self) -> bool { 179 matches!(self, Self::Dangling { .. }) 180 } 181}