Repository: diesel-rs/diesel
File: diesel/src/expression/cast.rs (Rust)

Code before:
}

impl<S, E, ST> FieldAliasMapper<S> for Cast<E, ST>
where
    S: AliasSource,
    E: FieldAliasMapper<S>,
{
    type Out = Cast<<E as FieldAliasMapper<S>>::Out, ST>;

    fn map(self, alias: &query_source::Alias<S>) -> Self::Out {
        Cast {
            expr: self.expr.map(alias),
            sql_type: self.sql_type,
        }
    }
}

/// Marker trait: this SQL type (`Self`) can be casted to the target SQL type
/// (`ST`) using `CAST(expr AS target_sql_type)`
pub trait CastsTo<ST> {}

impl<ST1, ST2> CastsTo<sql_types::Nullable<ST2>> for sql_types::Nullable<ST1> where ST1: CastsTo<ST2>
{}

impl CastsTo<sql_types::Int8> for sql_types::Int4 {}
impl CastsTo<sql_types::Int8> for sql_types::Text {}
impl CastsTo<sql_types::Int4> for sql_types::Int8 {}
impl CastsTo<sql_types::Int4> for sql_types::Text {}
#[cfg(all(feature = "uuid", feature = "postgres_backend"))]
impl CastsTo<sql_types::Uuid> for sql_types::Text {}
impl CastsTo<sql_types::Text> for sql_types::Int4 {}
impl CastsTo<sql_types::Text> for sql_types::Int8 {}
#[cfg(all(feature = "uuid", feature = "postgres_backend"))]
impl CastsTo<sql_types::Text> for sql_types::Uuid {}
impl CastsTo<sql_types::Text> for sql_types::Jsonb {}
impl CastsTo<sql_types::Text> for sql_types::Json {}
impl CastsTo<sql_types::Jsonb> for sql_types::Text {}
impl CastsTo<sql_types::Json> for sql_types::Text {}


Review comment (bug):
Yes I think I like the name `faillible_cast` you proposed for this kind of conversions: it feels like that would enable using the regular `cast` with more confidence, whereas otherwise every usage would have to be analyzed with great care when reviewing for correctness 🙂

(Regarding the other name you proposed, I feel like "faillible" expresses better what may happen than "assume", which may be useful.) 

Code after:
        Text => "text",
        Json => "json",
        Jsonb => "jsonb",
    }
}

impl<S, E, ST> FieldAliasMapper<S> for Cast<E, ST>
where
    S: AliasSource,
    E: FieldAliasMapper<S>,
{
    type Out = Cast<<E as FieldAliasMapper<S>>::Out, ST>;

    fn map(self, alias: &query_source::Alias<S>) -> Self::Out {
        Cast {
            expr: self.expr.map(alias),
            sql_type: self.sql_type,
        }
    }
}

/// Marker trait: this SQL type (`Self`) can be cast to the target SQL type, but some values can be invalid
pub trait FallibleCastsTo<ST> {}

impl<ST1, ST2> FallibleCastsTo<sql_types::Nullable<ST2>> for sql_types::Nullable<ST1> where
    ST1: CastsTo<ST2>
{
}

/// Marker trait: this SQL type (`Self`) can be cast to the target SQL type
/// (`ST`) using `CAST(expr AS target_sql_type)`
pub trait CastsTo<ST>: FallibleCastsTo<ST> {}

impl<ST1, ST2> CastsTo<sql_types::Nullable<ST2>> for sql_types::Nullable<ST1> where ST1: CastsTo<ST2>
{}

macro_rules! casts_impl {
    (
        $(
            $($feature: literal : )? ($to: tt <- $from: tt),
        )+
    ) => {
        $(
            $(#[cfg(feature = $feature)])?
            impl FallibleCastsTo<sql_types::$to> for sql_types::$from {}
            $(#[cfg(feature = $feature)])?
            impl CastsTo<sql_types::$to> for sql_types::$from {}
        )+
    };
}