bomboni_common 0.3.1

Common things for Bomboni library.
Documentation
use mysql_common::{FromValueError, Value, value::convert::FromValue};

use crate::id::{Id, ParseIdError};

mod ir {
    use super::{FromValue, FromValueError, Id, ParseIdError, Value};

    #[derive(Debug, Clone, Copy, Eq, PartialEq)]
    pub struct ParseIdIr<T: FromValue>(T::Intermediate, Id);

    impl TryFrom<Value> for ParseIdIr<String> {
        type Error = <<String as FromValue>::Intermediate as TryFrom<Value>>::Error;

        fn try_from(value: Value) -> Result<Self, Self::Error> {
            match value {
                Value::Bytes(bytes) => match String::from_utf8(bytes) {
                    Ok(x) => {
                        let id = x
                            .parse()
                            .map_err(|err: ParseIdError| FromValueError(err.to_string().into()))?;
                        Ok(Self(x, id))
                    }
                    Err(e) => Err(FromValueError(Value::Bytes(e.into_bytes()))),
                },
                v => Err(FromValueError(v)),
            }
        }
    }

    impl From<ParseIdIr<String>> for Id {
        fn from(ir: ParseIdIr<String>) -> Self {
            ir.1
        }
    }

    impl From<ParseIdIr<String>> for Value
    where
        <String as FromValue>::Intermediate: Into<Self>,
    {
        fn from(ir: ParseIdIr<String>) -> Self {
            ir.0.into()
        }
    }
}

pub use ir::ParseIdIr;

impl FromValue for Id {
    type Intermediate = ParseIdIr<String>;
}

impl From<Id> for Value {
    fn from(value: Id) -> Self {
        Self::Bytes(value.to_string().into_bytes())
    }
}