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::UnsupportedCapture => Self::UnsupportedCapture,
94 FailureReason::UnsupportedOperation => Self::UnsupportedOperation,
95 FailureReason::Internal => Self::Internal,
96 FailureReason::MatchBelowThreshold(comparison) => {
97 Self::MatchBelowThreshold {
98 comparison: comparison.into(),
99 }
100 }
101 FailureReason::MatchingFailed(comparison) => Self::MatchingFailed {
102 comparison: comparison.into(),
103 },
104 FailureReason::ImageRejected { image, reason } => Self::ImageRejected {
105 image: image.into(),
106 reason: reason.into(),
107 },
108 }
109 }
110}
111impl From<ComparisonRole> for FlamingoComparison {
112 fn from(value: ComparisonRole) -> Self {
113 match value {
114 ComparisonRole::OrbSelfie => Self::OrbSelfie,
115 ComparisonRole::OrbChallenge => Self::OrbChallenge,
116 ComparisonRole::SelfieChallenge => Self::SelfieChallenge,
117 }
118 }
119}
120impl From<ImageRole> for FlamingoImageRole {
121 fn from(value: ImageRole) -> Self {
122 match value {
123 ImageRole::OrbCredential => Self::OrbCredential,
124 ImageRole::LiveSelfie => Self::LiveSelfie,
125 ImageRole::RtmsChallenge => Self::RtmsChallenge,
126 }
127 }
128}
129#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
131pub enum FlamingoImageFailureReason {
132 InvalidImage,
134 TemplateFailed,
136 TooManyFaces,
138 ImageTooDark,
140 ImageTooBright,
142 IlluminationVariance,
144 FaceTooSmall,
146 FaceTooBig,
148 FaceResolutionTooLow,
150 FaceTooHigh,
152 FaceTooLow,
154 FaceTooFarLeft,
156 FaceTooFarRight,
158 HeadPoseYaw,
160 HeadPosePitchTooHigh,
162 HeadPosePitchTooLow,
164 HeadPoseRoll,
166 LowQuality,
168 SunglassesOcclusionDetected,
170 GlassesOcclusionDetected,
172 MaskOcclusionDetected,
174 OtherOcclusionDetected,
176 HairOcclusionDetected,
178 FasOcclusionDetected,
180 SpoofDetected,
182 DepthSpoofDetected,
184 ThermalSpoofDetected,
186 AgeBelowThreshold,
188 NoFaceDetected,
190 EyesClosed,
192 NonNeutralExpression,
194 LandmarksAlignment,
196 FaceOverexposed,
198 FaceUnderexposed,
200 SegmentationOcclusionProportion,
202 BrightArtifacts,
204 LightGuardScoreTooLow,
206 LowContrast,
208 MeshExpressionScore,
210 HighColorDistortion,
212 UnevenLighting,
214 BlurryFace,
216 NoisyThermalImage,
218}
219impl From<ImageFailureReason> for FlamingoImageFailureReason {
220 fn from(value: ImageFailureReason) -> Self {
221 match value {
222 ImageFailureReason::InvalidImage => Self::InvalidImage,
223 ImageFailureReason::TemplateFailed => Self::TemplateFailed,
224 ImageFailureReason::TooManyFaces => Self::TooManyFaces,
225 ImageFailureReason::ImageTooDark => Self::ImageTooDark,
226 ImageFailureReason::ImageTooBright => Self::ImageTooBright,
227 ImageFailureReason::IlluminationVariance => Self::IlluminationVariance,
228 ImageFailureReason::FaceTooSmall => Self::FaceTooSmall,
229 ImageFailureReason::FaceTooBig => Self::FaceTooBig,
230 ImageFailureReason::FaceResolutionTooLow => Self::FaceResolutionTooLow,
231 ImageFailureReason::FaceTooHigh => Self::FaceTooHigh,
232 ImageFailureReason::FaceTooLow => Self::FaceTooLow,
233 ImageFailureReason::FaceTooFarLeft => Self::FaceTooFarLeft,
234 ImageFailureReason::FaceTooFarRight => Self::FaceTooFarRight,
235 ImageFailureReason::HeadPoseYaw => Self::HeadPoseYaw,
236 ImageFailureReason::HeadPosePitchTooHigh => Self::HeadPosePitchTooHigh,
237 ImageFailureReason::HeadPosePitchTooLow => Self::HeadPosePitchTooLow,
238 ImageFailureReason::HeadPoseRoll => Self::HeadPoseRoll,
239 ImageFailureReason::LowQuality => Self::LowQuality,
240 ImageFailureReason::SunglassesOcclusionDetected => {
241 Self::SunglassesOcclusionDetected
242 }
243 ImageFailureReason::GlassesOcclusionDetected => {
244 Self::GlassesOcclusionDetected
245 }
246 ImageFailureReason::MaskOcclusionDetected => Self::MaskOcclusionDetected,
247 ImageFailureReason::OtherOcclusionDetected => Self::OtherOcclusionDetected,
248 ImageFailureReason::HairOcclusionDetected => Self::HairOcclusionDetected,
249 ImageFailureReason::FasOcclusionDetected => Self::FasOcclusionDetected,
250 ImageFailureReason::SpoofDetected => Self::SpoofDetected,
251 ImageFailureReason::DepthSpoofDetected => Self::DepthSpoofDetected,
252 ImageFailureReason::ThermalSpoofDetected => Self::ThermalSpoofDetected,
253 ImageFailureReason::AgeBelowThreshold => Self::AgeBelowThreshold,
254 ImageFailureReason::NoFaceDetected => Self::NoFaceDetected,
255 ImageFailureReason::EyesClosed => Self::EyesClosed,
256 ImageFailureReason::NonNeutralExpression => Self::NonNeutralExpression,
257 ImageFailureReason::LandmarksAlignment => Self::LandmarksAlignment,
258 ImageFailureReason::FaceOverexposed => Self::FaceOverexposed,
259 ImageFailureReason::FaceUnderexposed => Self::FaceUnderexposed,
260 ImageFailureReason::SegmentationOcclusionProportion => {
261 Self::SegmentationOcclusionProportion
262 }
263 ImageFailureReason::BrightArtifacts => Self::BrightArtifacts,
264 ImageFailureReason::LightGuardScoreTooLow => Self::LightGuardScoreTooLow,
265 ImageFailureReason::LowContrast => Self::LowContrast,
266 ImageFailureReason::MeshExpressionScore => Self::MeshExpressionScore,
267 ImageFailureReason::HighColorDistortion => Self::HighColorDistortion,
268 ImageFailureReason::UnevenLighting => Self::UnevenLighting,
269 ImageFailureReason::BlurryFace => Self::BlurryFace,
270 ImageFailureReason::NoisyThermalImage => Self::NoisyThermalImage,
271 }
272 }
273}