@@ -43,6 +43,46 @@ pub enum CuratedRecommendationLocale {
4343 #[ serde( rename = "de-CH" ) ]
4444 DeCh ,
4545}
46+
47+ impl CuratedRecommendationLocale {
48+ /// Returns all supported locale strings (e.g. `"en-US"`, `"fr-FR"`).
49+ ///
50+ /// These strings are the canonical serialized values of the enum variants.
51+ pub fn all_locales ( ) -> Vec < String > {
52+ vec ! [
53+ CuratedRecommendationLocale :: Fr ,
54+ CuratedRecommendationLocale :: FrFr ,
55+ CuratedRecommendationLocale :: Es ,
56+ CuratedRecommendationLocale :: EsEs ,
57+ CuratedRecommendationLocale :: It ,
58+ CuratedRecommendationLocale :: ItIt ,
59+ CuratedRecommendationLocale :: En ,
60+ CuratedRecommendationLocale :: EnCa ,
61+ CuratedRecommendationLocale :: EnGb ,
62+ CuratedRecommendationLocale :: EnUs ,
63+ CuratedRecommendationLocale :: De ,
64+ CuratedRecommendationLocale :: DeDe ,
65+ CuratedRecommendationLocale :: DeAt ,
66+ CuratedRecommendationLocale :: DeCh ,
67+ ]
68+ . into_iter ( )
69+ . map ( |l| {
70+ serde_json:: to_string ( & l)
71+ . unwrap ( )
72+ . trim_matches ( '"' )
73+ . to_string ( )
74+ } )
75+ . collect ( )
76+ }
77+
78+ /// Parses a locale string (e.g. `"en-US"`) into a `CuratedRecommendationLocale` enum variant.
79+ ///
80+ /// Returns `None` if the string does not match a known variant.
81+ pub fn from_locale_string ( locale : String ) -> Option < CuratedRecommendationLocale > {
82+ serde_json:: from_str ( & format ! ( "\" {}\" " , locale) ) . ok ( )
83+ }
84+ }
85+
4686// Configuration settings for a Section
4787#[ derive( Debug , Serialize , Deserialize , PartialEq , uniffi:: Record ) ]
4888pub struct SectionSettings {
@@ -259,3 +299,56 @@ pub struct Tile {
259299 #[ serde( rename = "hasExcerpt" ) ]
260300 pub has_excerpt : bool ,
261301}
302+
303+ #[ cfg( test) ]
304+ mod tests {
305+ use super :: * ;
306+
307+ #[ test]
308+ fn test_from_locale_string_valid_cases ( ) {
309+ assert_eq ! (
310+ CuratedRecommendationLocale :: from_locale_string( "en-US" . into( ) ) ,
311+ Some ( CuratedRecommendationLocale :: EnUs )
312+ ) ;
313+ assert_eq ! (
314+ CuratedRecommendationLocale :: from_locale_string( "fr" . into( ) ) ,
315+ Some ( CuratedRecommendationLocale :: Fr )
316+ ) ;
317+ }
318+
319+ #[ test]
320+ fn test_from_locale_string_invalid_cases ( ) {
321+ assert_eq ! (
322+ CuratedRecommendationLocale :: from_locale_string( "en_US" . into( ) ) ,
323+ None
324+ ) ;
325+ assert_eq ! (
326+ CuratedRecommendationLocale :: from_locale_string( "zz-ZZ" . into( ) ) ,
327+ None
328+ ) ;
329+ }
330+
331+ #[ test]
332+ fn test_all_locales_contains_expected_values ( ) {
333+ let locales = CuratedRecommendationLocale :: all_locales ( ) ;
334+ assert ! ( locales. contains( & "en-US" . to_string( ) ) ) ;
335+ assert ! ( locales. contains( & "de-CH" . to_string( ) ) ) ;
336+ assert ! ( locales. contains( & "fr" . to_string( ) ) ) ;
337+ }
338+
339+ #[ test]
340+ fn test_all_locales_round_trip ( ) {
341+ for locale_str in CuratedRecommendationLocale :: all_locales ( ) {
342+ let parsed = CuratedRecommendationLocale :: from_locale_string ( locale_str. clone ( ) ) ;
343+ assert ! ( parsed. is_some( ) , "Failed to parse locale: {}" , locale_str) ;
344+
345+ let reserialized = serde_json:: to_string ( & parsed. unwrap ( ) ) . unwrap ( ) ;
346+ let clean = reserialized. trim_matches ( '"' ) ;
347+ assert_eq ! (
348+ clean, locale_str,
349+ "Round-trip mismatch: {} => {}" ,
350+ locale_str, clean
351+ ) ;
352+ }
353+ }
354+ }
0 commit comments