Skip to content

Commit 547b12f

Browse files
refactor(rates): simplify fallback flow in MarketAPI
1 parent 4047a76 commit 547b12f

1 file changed

Lines changed: 39 additions & 18 deletions

File tree

crates/portal-rates/src/lib.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -282,20 +282,20 @@ impl MarketAPI {
282282
}
283283
}
284284

285-
async fn resolve_price_with_fallback<F, Fut>(
285+
async fn resolve_price_with_fallback(
286+
self: Arc<Self>,
286287
unit: &FiatUnit,
287-
mut fetcher: F,
288-
) -> Result<(String, Source), RatesError>
289-
where
290-
F: FnMut(&Source, &str) -> Fut,
291-
Fut: std::future::Future<Output = Result<Option<String>, RatesError>>,
292-
{
288+
) -> Result<(String, Source), RatesError> {
293289
let mut attempts = Vec::with_capacity(1 + Self::fallback_sources(&unit.source).len());
294290
attempts.push(unit.source.clone());
295291
attempts.extend(Self::fallback_sources(&unit.source));
296292

297293
for source in attempts {
298-
match fetcher(&source, &unit.end_point_key).await {
294+
match self
295+
.clone()
296+
.fetch_price_for_source(&source, &unit.end_point_key)
297+
.await
298+
{
299299
Ok(Some(price_str)) => return Ok((price_str, source)),
300300
Ok(None) => {
301301
log::debug!(
@@ -318,6 +318,30 @@ impl MarketAPI {
318318
Err(RatesError::MarketDataFetchFailed)
319319
}
320320

321+
#[cfg(test)]
322+
async fn resolve_price_with_fallback_with_fetcher<F, Fut>(
323+
unit: &FiatUnit,
324+
mut fetcher: F,
325+
) -> Result<(String, Source), RatesError>
326+
where
327+
F: FnMut(&Source, &str) -> Fut,
328+
Fut: std::future::Future<Output = Result<Option<String>, RatesError>>,
329+
{
330+
let mut attempts = Vec::with_capacity(1 + Self::fallback_sources(&unit.source).len());
331+
attempts.push(unit.source.clone());
332+
attempts.extend(Self::fallback_sources(&unit.source));
333+
334+
for source in attempts {
335+
match fetcher(&source, &unit.end_point_key).await {
336+
Ok(Some(price_str)) => return Ok((price_str, source)),
337+
Ok(None) => {}
338+
Err(_) => {}
339+
}
340+
}
341+
342+
Err(RatesError::MarketDataFetchFailed)
343+
}
344+
321345
async fn fetch_market_data_internal(
322346
self: Arc<Self>,
323347
currency: &str,
@@ -329,13 +353,10 @@ impl MarketAPI {
329353
None => return Err(RatesError::UnsupportedCurrency),
330354
};
331355

332-
let (price_str, used_source) = Self::resolve_price_with_fallback(&unit, |source, key| {
333-
let api = self.clone();
334-
let source = source.clone();
335-
let key = key.to_string();
336-
async move { api.fetch_price_for_source(&source, &key).await }
337-
})
338-
.await?;
356+
let (price_str, used_source) = self
357+
.clone()
358+
.resolve_price_with_fallback(&unit)
359+
.await?;
339360

340361
if let Ok(rate) = price_str.parse::<f64>() {
341362
let data = MarketData {
@@ -398,7 +419,7 @@ async fn test_fallback_primary_success() -> Result<(), RatesError> {
398419
let attempts = std::sync::Arc::new(std::sync::Mutex::new(Vec::<Source>::new()));
399420
let attempts_closure = attempts.clone();
400421

401-
let (price, used_source) = MarketAPI::resolve_price_with_fallback(&unit, move |source, _key| {
422+
let (price, used_source) = MarketAPI::resolve_price_with_fallback_with_fetcher(&unit, move |source, _key| {
402423
let attempts = attempts_closure.clone();
403424
let source = source.clone();
404425
async move {
@@ -429,7 +450,7 @@ async fn test_fallback_primary_fail_then_success() -> Result<(), RatesError> {
429450
let attempts = std::sync::Arc::new(std::sync::Mutex::new(Vec::<Source>::new()));
430451
let attempts_closure = attempts.clone();
431452

432-
let (price, used_source) = MarketAPI::resolve_price_with_fallback(&unit, move |source, _key| {
453+
let (price, used_source) = MarketAPI::resolve_price_with_fallback_with_fetcher(&unit, move |source, _key| {
433454
let attempts = attempts_closure.clone();
434455
let source = source.clone();
435456
async move {
@@ -463,7 +484,7 @@ async fn test_fallback_all_fail() {
463484
let attempts = std::sync::Arc::new(std::sync::Mutex::new(Vec::<Source>::new()));
464485
let attempts_closure = attempts.clone();
465486

466-
let result = MarketAPI::resolve_price_with_fallback(&unit, move |source, _key| {
487+
let result = MarketAPI::resolve_price_with_fallback_with_fetcher(&unit, move |source, _key| {
467488
let attempts = attempts_closure.clone();
468489
let source = source.clone();
469490
async move {

0 commit comments

Comments
 (0)