1use flamingo_verifier_sealed_types::{
2 ComparisonRole, FailureReason, ImageFailureReason, ImageRole,
3};
4use thiserror::Error;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
8pub enum FlamingoMatchRejection {
9 MalformedInputs,
11 InvalidHashesJson,
13 ThumbnailHashMismatch,
15 InvalidThreshold,
17 EmptyImage,
19 InputTooLarge,
21 UnsupportedCapture,
23 UnsupportedOperation,
25 MatchBelowThreshold {
27 comparison: FlamingoComparison,
29 },
30 ImageRejected {
32 image: FlamingoImageRole,
34 reason: FlamingoImageFailureReason,
36 },
37 MatchingFailed {
39 comparison: FlamingoComparison,
41 },
42 Internal,
44}
45#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
47pub enum FlamingoComparison {
48 OrbSelfie,
50 OrbChallenge,
52 SelfieChallenge,
54}
55#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
57pub enum FlamingoImageRole {
58 OrbCredential,
60 LiveSelfie,
62 RtmsChallenge,
64}
65#[derive(Debug, Error, uniffi::Error)]
67pub enum FlamingoError {
68 #[error("invalid {attribute}: {reason}")]
70 InvalidInput {
71 attribute: String,
73 reason: String,
75 },
76 #[error("invalid Flamingo verifier configuration: {0}")]
78 Configuration(String),
79 #[error("Flamingo verifier request failed: {0}")]
81 Verifier(String),
82}
83
84impl From<FailureReason> for FlamingoMatchRejection {
85 fn from(value: FailureReason) -> Self {
86 match value {
87 FailureReason::MalformedInputs => Self::MalformedInputs,
88 FailureReason::InvalidHashesJson => Self::InvalidHashesJson,
89 FailureReason::ThumbnailHashMismatch => Self::ThumbnailHashMismatch,
90 FailureReason::InvalidThreshold => Self::InvalidThreshold,
91 FailureReason::EmptyImage => Self::EmptyImage,
92 FailureReason::InputTooLarge => Self::InputTooLarge,
93 FailureReason::Internal => Self::Internal,
94 FailureReason::MatchBelowThreshold(comparison) => {
95 Self::MatchBelowThreshold {
96 comparison: comparison.into(),
97 }
98 }
99 FailureReason::MatchingFailed(comparison) => Self::MatchingFailed {
100 comparison: comparison.into(),
101 },
102 FailureReason::ImageRejected { image, reason } => Self::ImageRejected {
103 image: image.into(),
104 reason: reason.into(),
105 },
106 }
107 }
108}
109impl From<ComparisonRole> for FlamingoComparison {
110 fn from(value: ComparisonRole) -> Self {
111 match value {
112 ComparisonRole::OrbSelfie => Self::OrbSelfie,
113 ComparisonRole::OrbChallenge => Self::OrbChallenge,
114 ComparisonRole::SelfieChallenge => Self::SelfieChallenge,
115 }
116 }
117}
118impl From<ImageRole> for FlamingoImageRole {
119 fn from(value: ImageRole) -> Self {
120 match value {
121 ImageRole::OrbCredential => Self::OrbCredential,
122 ImageRole::LiveSelfie => Self::LiveSelfie,
123 ImageRole::RtmsChallenge => Self::RtmsChallenge,
124 }
125 }
126}
127#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
129pub enum FlamingoImageFailureReason {
130 InvalidImage,
132 TemplateFailed,
134 TooManyFaces,
136 ImageTooDark,
138 ImageTooBright,
140 IlluminationVariance,
142 FaceTooSmall,
144 FaceTooBig,
146 FaceResolutionTooLow,
148 FaceTooHigh,
150 FaceTooLow,
152 FaceTooFarLeft,
154 FaceTooFarRight,
156 HeadPoseYaw,
158 HeadPosePitchTooHigh,
160 HeadPosePitchTooLow,
162 HeadPoseRoll,
164 LowQuality,
166 SunglassesOcclusionDetected,
168 GlassesOcclusionDetected,
170 MaskOcclusionDetected,
172 OtherOcclusionDetected,
174 HairOcclusionDetected,
176 FasOcclusionDetected,
178 SpoofDetected,
180 DepthSpoofDetected,
182 ThermalSpoofDetected,
184 AgeBelowThreshold,
186 NoFaceDetected,
188 EyesClosed,
190 NonNeutralExpression,
192 LandmarksAlignment,
194 FaceOverexposed,
196 FaceUnderexposed,
198 SegmentationOcclusionProportion,
200 BrightArtifacts,
202 LightGuardScoreTooLow,
204 LowContrast,
206 MeshExpressionScore,
208 HighColorDistortion,
210 UnevenLighting,
212 BlurryFace,
214 NoisyThermalImage,
216}
217impl From<ImageFailureReason> for FlamingoImageFailureReason {
218 fn from(value: ImageFailureReason) -> Self {
219 match value {
220 ImageFailureReason::InvalidImage => Self::InvalidImage,
221 ImageFailureReason::TemplateFailed => Self::TemplateFailed,
222 ImageFailureReason::TooManyFaces => Self::TooManyFaces,
223 ImageFailureReason::ImageTooDark => Self::ImageTooDark,
224 ImageFailureReason::ImageTooBright => Self::ImageTooBright,
225 ImageFailureReason::IlluminationVariance => Self::IlluminationVariance,
226 ImageFailureReason::FaceTooSmall => Self::FaceTooSmall,
227 ImageFailureReason::FaceTooBig => Self::FaceTooBig,
228 ImageFailureReason::FaceResolutionTooLow => Self::FaceResolutionTooLow,
229 ImageFailureReason::FaceTooHigh => Self::FaceTooHigh,
230 ImageFailureReason::FaceTooLow => Self::FaceTooLow,
231 ImageFailureReason::FaceTooFarLeft => Self::FaceTooFarLeft,
232 ImageFailureReason::FaceTooFarRight => Self::FaceTooFarRight,
233 ImageFailureReason::HeadPoseYaw => Self::HeadPoseYaw,
234 ImageFailureReason::HeadPosePitchTooHigh => Self::HeadPosePitchTooHigh,
235 ImageFailureReason::HeadPosePitchTooLow => Self::HeadPosePitchTooLow,
236 ImageFailureReason::HeadPoseRoll => Self::HeadPoseRoll,
237 ImageFailureReason::LowQuality => Self::LowQuality,
238 ImageFailureReason::SunglassesOcclusionDetected => {
239 Self::SunglassesOcclusionDetected
240 }
241 ImageFailureReason::GlassesOcclusionDetected => {
242 Self::GlassesOcclusionDetected
243 }
244 ImageFailureReason::MaskOcclusionDetected => Self::MaskOcclusionDetected,
245 ImageFailureReason::OtherOcclusionDetected => Self::OtherOcclusionDetected,
246 ImageFailureReason::HairOcclusionDetected => Self::HairOcclusionDetected,
247 ImageFailureReason::FasOcclusionDetected => Self::FasOcclusionDetected,
248 ImageFailureReason::SpoofDetected => Self::SpoofDetected,
249 ImageFailureReason::DepthSpoofDetected => Self::DepthSpoofDetected,
250 ImageFailureReason::ThermalSpoofDetected => Self::ThermalSpoofDetected,
251 ImageFailureReason::AgeBelowThreshold => Self::AgeBelowThreshold,
252 ImageFailureReason::NoFaceDetected => Self::NoFaceDetected,
253 ImageFailureReason::EyesClosed => Self::EyesClosed,
254 ImageFailureReason::NonNeutralExpression => Self::NonNeutralExpression,
255 ImageFailureReason::LandmarksAlignment => Self::LandmarksAlignment,
256 ImageFailureReason::FaceOverexposed => Self::FaceOverexposed,
257 ImageFailureReason::FaceUnderexposed => Self::FaceUnderexposed,
258 ImageFailureReason::SegmentationOcclusionProportion => {
259 Self::SegmentationOcclusionProportion
260 }
261 ImageFailureReason::BrightArtifacts => Self::BrightArtifacts,
262 ImageFailureReason::LightGuardScoreTooLow => Self::LightGuardScoreTooLow,
263 ImageFailureReason::LowContrast => Self::LowContrast,
264 ImageFailureReason::MeshExpressionScore => Self::MeshExpressionScore,
265 ImageFailureReason::HighColorDistortion => Self::HighColorDistortion,
266 ImageFailureReason::UnevenLighting => Self::UnevenLighting,
267 ImageFailureReason::BlurryFace => Self::BlurryFace,
268 ImageFailureReason::NoisyThermalImage => Self::NoisyThermalImage,
269 }
270 }
271}