apollo-federation 2.13.1

Apollo Federation
Documentation
//! This module contains various tools that help the ergonomics of this crate.

mod fallible_iterator;
pub(crate) mod human_readable;
pub(crate) mod logging;
pub(crate) mod multi_index_map;
pub mod normalize_schema;
pub(crate) mod serde_bridge;

use std::cell::OnceCell;

// Re-exports
pub(crate) use fallible_iterator::*;
pub(crate) use multi_index_map::MultiIndexMap;

/// If the `iter` yields a single element, return it. Else return `None`.
pub(crate) fn iter_into_single_item<T>(mut iter: impl Iterator<Item = T>) -> Option<T> {
    let item = iter.next()?;
    if iter.next().is_none() {
        Some(item)
    } else {
        None
    }
}

/// An alternative to Itertools' `max_by_key` which breaks ties by returning the first element with
/// the maximum key, rather than the last.
pub(crate) fn first_max_by_key<T, O: Ord>(
    iter: impl Iterator<Item = T>,
    f: impl Fn(&T) -> O,
) -> Option<T> {
    let mut iter = iter.peekable();
    let first = iter.next()?;
    let mut max_item = first;
    let mut max_key = f(&max_item);

    for item in iter {
        let key = f(&item);
        if key > max_key {
            max_key = key;
            max_item = item;
        }
    }

    Some(max_item)
}

/// Wrapper around OnceCell that allows fallible instantiation.
///
/// NOTE: This is a temporary workaround until `OnceCell#get_or_try_init` stabilizes
pub(crate) struct FallibleOnceCell<T>(OnceCell<T>);

impl<T: std::fmt::Debug> FallibleOnceCell<T> {
    pub(crate) fn new() -> Self {
        Self(OnceCell::new())
    }

    pub(crate) fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
    where
        F: FnOnce() -> Result<T, E>,
    {
        let value = match self.0.get() {
            Some(value) => value,
            None => {
                let value = f()?;
                self.0.set(value).unwrap();
                // we just set the value so this should never return None
                self.0.get().unwrap()
            }
        };
        Ok(value)
    }
}