1use flamingo_verifier_sealed_types::{
2 ComparisonRole, FailureReason, ImageFailureReason, ImageRole, InputFailureReason,
3 ValidationTarget,
4};
5use thiserror::Error;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
9pub enum FlamingoMatchRejection {
10 MalformedInputs,
12 InvalidHashesJson,
14 ThumbnailHashMismatch,
16 InvalidThreshold,
18 InputRejected {
20 reason: FlamingoInputFailureReason,
22 image: Option<FlamingoImageRole>,
24 limit_bytes: Option<u64>,
26 },
27 MatchBelowThreshold {
29 comparison: FlamingoComparison,
31 },
32 ImageRejected {
34 image: FlamingoImageRole,
36 reason: FlamingoImageFailureReason,
38 target: Option<FlamingoValidationTarget>,
40 },
41 MatchingFailed {
43 comparison: FlamingoComparison,
45 },
46 Internal,
48}
49#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
51pub enum FlamingoComparison {
52 OrbSelfie,
54 OrbChallenge,
56 SelfieChallenge,
58}
59#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
61pub enum FlamingoImageRole {
62 OrbCredential,
64 LiveSelfie,
66 RtmsChallenge,
68}
69#[derive(Debug, Error, uniffi::Error)]
71pub enum FlamingoError {
72 #[error("invalid {attribute}: {reason}")]
74 InvalidInput {
75 attribute: String,
77 reason: String,
79 kind: FlamingoInputFailureKind,
81 limit_bytes: Option<u64>,
83 },
84 #[error("invalid Flamingo verifier configuration: {0}")]
86 Configuration(String),
87 #[error("Flamingo service error ({code})")]
89 Service {
90 code: String,
92 allow_retry: bool,
94 },
95 #[error("Flamingo request timed out")]
97 Timeout,
98 #[error("Flamingo transport failed: {details}")]
100 Transport {
101 details: String,
103 },
104 #[error("invalid Flamingo response at {stage:?}")]
106 InvalidResponse {
107 stage: FlamingoResponseStage,
109 },
110 #[error("Flamingo attestation failed: {details}")]
112 Attestation {
113 details: String,
115 },
116 #[error("Flamingo channel failed: {details}")]
118 Channel {
119 details: String,
121 },
122 #[error("invalid Flamingo signing key")]
124 InvalidSigningKey,
125 #[error("invalid Flamingo match statement")]
127 StatementInvalid,
128 #[error("Flamingo reassignment retry exhausted")]
130 ReassignmentRequired,
131}
132
133impl From<FailureReason> for FlamingoMatchRejection {
134 fn from(value: FailureReason) -> Self {
135 match value {
136 FailureReason::MalformedInputs => Self::MalformedInputs,
137 FailureReason::InvalidHashesJson => Self::InvalidHashesJson,
138 FailureReason::ThumbnailHashMismatch => Self::ThumbnailHashMismatch,
139 FailureReason::InvalidThreshold => Self::InvalidThreshold,
140 FailureReason::InputRejected {
141 reason,
142 image,
143 limit_bytes,
144 } => Self::InputRejected {
145 reason: reason.into(),
146 image: image.map(Into::into),
147 limit_bytes,
148 },
149 FailureReason::Internal => Self::Internal,
150 FailureReason::MatchBelowThreshold(comparison) => {
151 Self::MatchBelowThreshold {
152 comparison: comparison.into(),
153 }
154 }
155 FailureReason::MatchingFailed(comparison) => Self::MatchingFailed {
156 comparison: comparison.into(),
157 },
158 FailureReason::ImageRejected {
159 image,
160 reason,
161 target,
162 } => Self::ImageRejected {
163 image: image.into(),
164 reason: reason.into(),
165 target: target.map(Into::into),
166 },
167 }
168 }
169}
170impl From<ComparisonRole> for FlamingoComparison {
171 fn from(value: ComparisonRole) -> Self {
172 match value {
173 ComparisonRole::OrbSelfie => Self::OrbSelfie,
174 ComparisonRole::OrbChallenge => Self::OrbChallenge,
175 ComparisonRole::SelfieChallenge => Self::SelfieChallenge,
176 }
177 }
178}
179impl From<ImageRole> for FlamingoImageRole {
180 fn from(value: ImageRole) -> Self {
181 match value {
182 ImageRole::OrbCredential => Self::OrbCredential,
183 ImageRole::LiveSelfie => Self::LiveSelfie,
184 ImageRole::RtmsChallenge => Self::RtmsChallenge,
185 }
186 }
187}
188#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
190pub enum FlamingoImageFailureReason {
191 InvalidImage,
193 TemplateFailed,
195 TooManyFaces,
197 ImageTooDark,
199 ImageTooBright,
201 IlluminationVariance,
203 FaceTooSmall,
205 FaceTooBig,
207 FaceResolutionTooLow,
209 FaceTooHigh,
211 FaceTooLow,
213 FaceTooFarLeft,
215 FaceTooFarRight,
217 HeadPoseYaw,
219 HeadPosePitchTooHigh,
221 HeadPosePitchTooLow,
223 HeadPoseRoll,
225 LowQuality,
227 SunglassesOcclusionDetected,
229 GlassesOcclusionDetected,
231 MaskOcclusionDetected,
233 OtherOcclusionDetected,
235 HairOcclusionDetected,
237 FasOcclusionDetected,
239 SpoofDetected,
241 DepthSpoofDetected,
243 ThermalSpoofDetected,
245 AgeBelowThreshold,
247 NoFaceDetected,
249 EyesClosed,
251 NonNeutralExpression,
253 LandmarksAlignment,
255 FaceOverexposed,
257 FaceUnderexposed,
259 SegmentationOcclusionProportion,
261 BrightArtifacts,
263 LightGuardScoreTooLow,
265 LowContrast,
267 MeshExpressionScore,
269 HighColorDistortion,
271 UnevenLighting,
273 BlurryFace,
275 NoisyThermalImage,
277}
278impl From<ImageFailureReason> for FlamingoImageFailureReason {
279 fn from(value: ImageFailureReason) -> Self {
280 match value {
281 ImageFailureReason::InvalidImage => Self::InvalidImage,
282 ImageFailureReason::TemplateFailed => Self::TemplateFailed,
283 ImageFailureReason::TooManyFaces => Self::TooManyFaces,
284 ImageFailureReason::ImageTooDark => Self::ImageTooDark,
285 ImageFailureReason::ImageTooBright => Self::ImageTooBright,
286 ImageFailureReason::IlluminationVariance => Self::IlluminationVariance,
287 ImageFailureReason::FaceTooSmall => Self::FaceTooSmall,
288 ImageFailureReason::FaceTooBig => Self::FaceTooBig,
289 ImageFailureReason::FaceResolutionTooLow => Self::FaceResolutionTooLow,
290 ImageFailureReason::FaceTooHigh => Self::FaceTooHigh,
291 ImageFailureReason::FaceTooLow => Self::FaceTooLow,
292 ImageFailureReason::FaceTooFarLeft => Self::FaceTooFarLeft,
293 ImageFailureReason::FaceTooFarRight => Self::FaceTooFarRight,
294 ImageFailureReason::HeadPoseYaw => Self::HeadPoseYaw,
295 ImageFailureReason::HeadPosePitchTooHigh => Self::HeadPosePitchTooHigh,
296 ImageFailureReason::HeadPosePitchTooLow => Self::HeadPosePitchTooLow,
297 ImageFailureReason::HeadPoseRoll => Self::HeadPoseRoll,
298 ImageFailureReason::LowQuality => Self::LowQuality,
299 ImageFailureReason::SunglassesOcclusionDetected => {
300 Self::SunglassesOcclusionDetected
301 }
302 ImageFailureReason::GlassesOcclusionDetected => {
303 Self::GlassesOcclusionDetected
304 }
305 ImageFailureReason::MaskOcclusionDetected => Self::MaskOcclusionDetected,
306 ImageFailureReason::OtherOcclusionDetected => Self::OtherOcclusionDetected,
307 ImageFailureReason::HairOcclusionDetected => Self::HairOcclusionDetected,
308 ImageFailureReason::FasOcclusionDetected => Self::FasOcclusionDetected,
309 ImageFailureReason::SpoofDetected => Self::SpoofDetected,
310 ImageFailureReason::DepthSpoofDetected => Self::DepthSpoofDetected,
311 ImageFailureReason::ThermalSpoofDetected => Self::ThermalSpoofDetected,
312 ImageFailureReason::AgeBelowThreshold => Self::AgeBelowThreshold,
313 ImageFailureReason::NoFaceDetected => Self::NoFaceDetected,
314 ImageFailureReason::EyesClosed => Self::EyesClosed,
315 ImageFailureReason::NonNeutralExpression => Self::NonNeutralExpression,
316 ImageFailureReason::LandmarksAlignment => Self::LandmarksAlignment,
317 ImageFailureReason::FaceOverexposed => Self::FaceOverexposed,
318 ImageFailureReason::FaceUnderexposed => Self::FaceUnderexposed,
319 ImageFailureReason::SegmentationOcclusionProportion => {
320 Self::SegmentationOcclusionProportion
321 }
322 ImageFailureReason::BrightArtifacts => Self::BrightArtifacts,
323 ImageFailureReason::LightGuardScoreTooLow => Self::LightGuardScoreTooLow,
324 ImageFailureReason::LowContrast => Self::LowContrast,
325 ImageFailureReason::MeshExpressionScore => Self::MeshExpressionScore,
326 ImageFailureReason::HighColorDistortion => Self::HighColorDistortion,
327 ImageFailureReason::UnevenLighting => Self::UnevenLighting,
328 ImageFailureReason::BlurryFace => Self::BlurryFace,
329 ImageFailureReason::NoisyThermalImage => Self::NoisyThermalImage,
330 }
331 }
332}
333
334#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
336pub enum FlamingoValidationTarget {
337 Image,
339 IlluminatedFrame,
341 UnilluminatedFrame,
343 LightGuardPair,
345}
346impl From<ValidationTarget> for FlamingoValidationTarget {
347 fn from(value: ValidationTarget) -> Self {
348 match value {
349 ValidationTarget::Image => Self::Image,
350 ValidationTarget::IlluminatedFrame => Self::IlluminatedFrame,
351 ValidationTarget::UnilluminatedFrame => Self::UnilluminatedFrame,
352 ValidationTarget::LightGuardPair => Self::LightGuardPair,
353 }
354 }
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
359pub enum FlamingoInputFailureReason {
360 MissingImage,
362 MissingSource,
364 InvalidMatchingFrame,
366 EmptyImage,
368 ImageTooLarge,
370 TotalImagesTooLarge,
372}
373impl From<InputFailureReason> for FlamingoInputFailureReason {
374 fn from(value: InputFailureReason) -> Self {
375 match value {
376 InputFailureReason::MissingImage => Self::MissingImage,
377 InputFailureReason::MissingSource => Self::MissingSource,
378 InputFailureReason::InvalidMatchingFrame => Self::InvalidMatchingFrame,
379 InputFailureReason::EmptyImage => Self::EmptyImage,
380 InputFailureReason::ImageTooLarge => Self::ImageTooLarge,
381 InputFailureReason::TotalImagesTooLarge => Self::TotalImagesTooLarge,
382 }
383 }
384}
385
386#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
388pub enum FlamingoInputFailureKind {
389 Empty,
391 TooLarge,
393 TotalTooLarge,
395 InvalidThreshold,
397}
398
399#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
401pub enum FlamingoResponseStage {
402 Assignment,
404 HostMessage,
406 MatchResult,
408}