From b8c4e46415e831d399616e41a442850beef084b3 Mon Sep 17 00:00:00 2001 From: Ben Dean-Kawamura Date: Fri, 5 Jun 2026 09:29:38 -0400 Subject: [PATCH] merino/relevancy/suggest: Refactorings for `uniffi_parse_rs` I'm working on a new UniFFI parser (https://github.com/mozilla/uniffi-rs/pull/2841) and it currently has a couple extra requirements for types used in exported functions: * The types are publicly available from other crates. * The name matches the one used in the `custom_type!` macro. * Macro expansion is not supported, the types need to be written out by hand. I could maybe rework the parser to avoid these requirements, but the first two the changes feel like improvements to me. Not being able to use macros for UniFFIed types is worse but I don't think it will affect us all that much in practice. Please push back if you don't think so. --- .../merino/src/curated_recommendations/mod.rs | 4 +- .../curated_recommendations/models/locale.rs | 130 +++++++++++------- components/merino/src/lib.rs | 1 + components/relevancy/src/lib.rs | 2 +- components/suggest/src/lib.rs | 6 +- components/suggest/src/suggestion.rs | 4 +- 6 files changed, 89 insertions(+), 58 deletions(-) diff --git a/components/merino/src/curated_recommendations/mod.rs b/components/merino/src/curated_recommendations/mod.rs index d1421e2375..afde339957 100644 --- a/components/merino/src/curated_recommendations/mod.rs +++ b/components/merino/src/curated_recommendations/mod.rs @@ -16,11 +16,11 @@ pub mod models; #[cfg(test)] mod tests; -use crate::curated_recommendations::models::locale::CuratedRecommendationLocale; +pub use crate::curated_recommendations::models::locale::CuratedRecommendationLocale; use crate::curated_recommendations::models::request::CuratedRecommendationsConfig; use crate::curated_recommendations::models::request::CuratedRecommendationsRequest; use crate::curated_recommendations::models::response::CuratedRecommendationsResponse; -pub use error::{ApiResult, Error, Result}; +pub use error::{ApiResult, CuratedRecommendationsApiError, Error, Result}; use error_support::handle_error; use url::Url; diff --git a/components/merino/src/curated_recommendations/models/locale.rs b/components/merino/src/curated_recommendations/models/locale.rs index 6bf1dcf63c..5c0608bb73 100644 --- a/components/merino/src/curated_recommendations/models/locale.rs +++ b/components/merino/src/curated_recommendations/models/locale.rs @@ -5,59 +5,87 @@ use serde::{Deserialize, Serialize}; -/// Defines the `CuratedRecommendationLocale` enum along with `all_locales()` and -/// `from_locale_string()` methods, ensuring the variant list is specified exactly once. -macro_rules! define_locales { - ( $( $variant:ident => $str:literal ),+ $(,)? ) => { - /// Locales supported by Merino curated recommendations. - /// - /// Each variant maps to a BCP 47 locale string (e.g. `"en-US"`, `"fr"`) used when - /// requesting recommendations from the Merino API. - #[derive(Debug, Serialize, PartialEq, Deserialize, uniffi::Enum)] - pub enum CuratedRecommendationLocale { - $( - #[serde(rename = $str)] - $variant, - )+ - } - - impl CuratedRecommendationLocale { - /// Returns all supported locale strings (e.g. `"en-US"`, `"fr-FR"`). - /// - /// These strings are the canonical serialized values of the enum variants. - pub fn all_locales() -> Vec { - vec![ $( $str.to_string(), )+ ] - } - - /// Parses a locale string (e.g. `"en-US"`) into a `CuratedRecommendationLocale` - /// enum variant. - /// - /// Returns `None` if the string does not match a known variant. - pub fn from_locale_string(locale: String) -> Option { - match locale.as_str() { - $( $str => Some(CuratedRecommendationLocale::$variant), )+ - _ => None, - } - } - } - }; +/// Locales supported by Merino curated recommendations. +/// +/// Each variant maps to a BCP 47 locale string (e.g. `"en-US"`, `"fr"`) used when +/// requesting recommendations from the Merino API. +#[derive(Debug, Serialize, PartialEq, Deserialize, uniffi::Enum)] +pub enum CuratedRecommendationLocale { + #[serde(rename = "fr")] + Fr, + #[serde(rename = "fr-FR")] + FrFr, + #[serde(rename = "es")] + Es, + #[serde(rename = "es-ES")] + EsEs, + #[serde(rename = "it")] + It, + #[serde(rename = "it-IT")] + ItIt, + #[serde(rename = "en")] + En, + #[serde(rename = "en-CA")] + EnCa, + #[serde(rename = "en-GB")] + EnGb, + #[serde(rename = "en-US")] + EnUs, + #[serde(rename = "de")] + De, + #[serde(rename = "de-DE")] + DeDe, + #[serde(rename = "de-AT")] + DeAt, + #[serde(rename = "de-CH")] + DeCh, } +impl CuratedRecommendationLocale { + /// Returns all supported locale strings (e.g. `"en-US"`, `"fr-FR"`). + /// + /// These strings are the canonical serialized values of the enum variants. + pub fn all_locales() -> Vec { + vec![ + "fr".to_string(), + "fr-FR".to_string(), + "es".to_string(), + "es-ES".to_string(), + "it".to_string(), + "it-IT".to_string(), + "en".to_string(), + "en-CA".to_string(), + "en-GB".to_string(), + "en-US".to_string(), + "de".to_string(), + "de-DE".to_string(), + "de-AT".to_string(), + "de-CH".to_string(), + ] + } -define_locales! { - Fr => "fr", - FrFr => "fr-FR", - Es => "es", - EsEs => "es-ES", - It => "it", - ItIt => "it-IT", - En => "en", - EnCa => "en-CA", - EnGb => "en-GB", - EnUs => "en-US", - De => "de", - DeDe => "de-DE", - DeAt => "de-AT", - DeCh => "de-CH", + /// Parses a locale string (e.g. `"en-US"`) into a `CuratedRecommendationLocale` + /// enum variant. + /// + /// Returns `None` if the string does not match a known variant. + pub fn from_locale_string(locale: String) -> Option { + match locale.as_str() { + "fr" => Some(CuratedRecommendationLocale::Fr), + "fr-FR" => Some(CuratedRecommendationLocale::FrFr), + "es" => Some(CuratedRecommendationLocale::Es), + "es-ES" => Some(CuratedRecommendationLocale::EsEs), + "it" => Some(CuratedRecommendationLocale::It), + "it-IT" => Some(CuratedRecommendationLocale::ItIt), + "en" => Some(CuratedRecommendationLocale::En), + "en-CA" => Some(CuratedRecommendationLocale::EnCa), + "en-GB" => Some(CuratedRecommendationLocale::EnGb), + "en-US" => Some(CuratedRecommendationLocale::EnUs), + "de" => Some(CuratedRecommendationLocale::De), + "de-DE" => Some(CuratedRecommendationLocale::DeDe), + "de-AT" => Some(CuratedRecommendationLocale::DeAt), + "de-CH" => Some(CuratedRecommendationLocale::DeCh), + _ => None, + } + } } #[cfg(test)] diff --git a/components/merino/src/lib.rs b/components/merino/src/lib.rs index 5ce7393f12..8dd0504dcf 100644 --- a/components/merino/src/lib.rs +++ b/components/merino/src/lib.rs @@ -21,4 +21,5 @@ pub mod curated_recommendations; pub mod suggest; pub mod worldcup; +pub use curated_recommendations::{CuratedRecommendationLocale, CuratedRecommendationsApiError}; uniffi::setup_scaffolding!("merino"); diff --git a/components/relevancy/src/lib.rs b/components/relevancy/src/lib.rs index b279e940dc..671c01615c 100644 --- a/components/relevancy/src/lib.rs +++ b/components/relevancy/src/lib.rs @@ -35,7 +35,7 @@ pub use ranker::score; use error_support::handle_error; -use db::BanditData; +pub use db::BanditData; uniffi::setup_scaffolding!(); diff --git a/components/suggest/src/lib.rs b/components/suggest/src/lib.rs index 5603403bc5..d8b9adfdf4 100644 --- a/components/suggest/src/lib.rs +++ b/components/suggest/src/lib.rs @@ -24,12 +24,14 @@ mod yelp; pub use config::{SuggestGlobalConfig, SuggestProviderConfig}; pub use error::{Error, SuggestApiError}; -pub use geoname::{Geoname, GeonameMatch}; +pub use geoname::{ + AlternateNames, Geoname, GeonameAlternates, GeonameMatch, GeonameMatchType, GeonameType, +}; pub use metrics::{LabeledTimingSample, SuggestIngestionMetrics}; pub use provider::{AmpMatchingStrategy, SuggestionProvider, SuggestionProviderConstraints}; pub use query::{QueryWithMetricsResult, SuggestionQuery}; pub use store::{InterruptKind, SuggestIngestionConstraints, SuggestStore, SuggestStoreBuilder}; -pub use suggestion::{raw_suggestion_url_matches, Suggestion}; +pub use suggestion::{raw_suggestion_url_matches, FtsMatchInfo, Suggestion, YelpSubjectType}; pub(crate) type Result = std::result::Result; pub type SuggestApiResult = std::result::Result; diff --git a/components/suggest/src/suggestion.rs b/components/suggest/src/suggestion.rs index b9ed8608ec..692544efc5 100644 --- a/components/suggest/src/suggestion.rs +++ b/components/suggest/src/suggestion.rs @@ -5,7 +5,7 @@ use chrono::Local; -use crate::{db::DEFAULT_SUGGESTION_SCORE, geoname::Geoname}; +use crate::{db::DEFAULT_SUGGESTION_SCORE, geoname::Geoname, JsonValue}; /// The template parameter for a timestamp in a "raw" sponsored suggestion URL. const TIMESTAMP_TEMPLATE: &str = "%YYYYMMDDHH%"; @@ -86,7 +86,7 @@ pub enum Suggestion { }, Dynamic { suggestion_type: String, - data: Option, + data: Option, /// This value is optionally defined in the suggestion's remote settings /// data and is an opaque token used for dismissing the suggestion in /// lieu of a URL. If `Some`, the suggestion can be dismissed by passing