cached-pair 0.10.0

A simple pair of values, where the one can be convertible to the other.
Documentation

Crates.io Version docs.rs

cached-pair

A simple library for caching pairs of values. Similar to EitherOrBoth in the itertools crate, but with an extra assumption that both values are convertible to each other, and the conversion may be non-trivial or expensive.

For example, you can use this library to hold a pair of values that need to be kept in sync, such as a number and its string representation, or a binary Vec<u8> and its base64 encoded String.

Examples

Basic Usage with Function Converter

You can use the fn_converter function to create a converter between two types using closures.

use cached_pair::{Pair, fn_converter};
use std::convert::Infallible;
use std::num::ParseIntError;

// Create a converter between i32 and String using fn_converter
let converter = fn_converter(
    |s: &String| s.parse::<i32>(),  // String -> i32 (may fail)
    |i: &i32| Ok(i.to_string()),    // i32 -> String (never fails)
);

// Create a pair from a left value
let pair = Pair::from_left_conv(42i32, converter);

// Access values
assert_eq!(pair.left_opt(), Some(&42));
assert_eq!(pair.try_right(), Ok(&"42".to_string()));

// The converted value is now cached
assert_eq!(pair.right_opt(), Some(&"42".to_string()));

Using the Standard Converter

For types that implement TryFrom traits, you can use the default StdConverter.

use cached_pair::Pair;
use std::convert::Infallible;

// Define types that implement TryFrom for each other
#[derive(Debug, PartialEq)]
struct Small(u8);

#[derive(Debug, PartialEq)]
struct Large(u32);

impl TryFrom<&Large> for Small {
    type Error = std::num::TryFromIntError;
    fn try_from(value: &Large) -> Result<Self, Self::Error> {
        value.0.try_into().map(Small)
    }
}

impl TryFrom<&Small> for Large {
    type Error = Infallible;
    fn try_from(value: &Small) -> Result<Self, Self::Error> {
        Ok(Large(value.0 as u32))
    }
}

// Create a pair using the default StdConverter
let pair = Pair::from_left(Small(42));
assert_eq!(pair.try_right(), Ok(&Large(42)));

// Conversion may fail if the value is too large
let pair = Pair::from_right(Large(300));
assert!(pair.try_left().is_err());