Repository: diesel-rs/diesel
File: diesel/src/pg/types/multirange.rs (Rust)

Code before:
        (0..len)
            .map(|_| {
                let range_size = bytes.read_i32::<NetworkEndian>()?;
                let (range_bytes, new_bytes) = bytes.split_at(range_size as usize);
                bytes = new_bytes;
                FromSql::from_sql(PgValue::new_internal(range_bytes, &value))
            })
            .collect()
    }
}

#[cfg(feature = "postgres_backend")]
impl<T, ST> ToSql<Multirange<ST>, Pg> for [(Bound<T>, Bound<T>)]
where
    T: ToSql<ST, Pg>,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_u32::<NetworkEndian>(self.len() as u32)?;

        let mut buffer = Vec::new();
        for value in self {
            {
                let mut inner_buffer = Output::new(ByteWrapper(&mut buffer), out.metadata_lookup());
                ToSql::<Range<ST>, Pg>::to_sql(&value, &mut inner_buffer)?;
            }
            out.write_u32::<NetworkEndian>(buffer.len() as u32)?;
            out.write_all(&buffer)?;
            buffer.clear();
        }

        Ok(IsNull::No)
    }
}

#[cfg(feature = "postgres_backend")]
impl<T, ST> ToSql<Multirange<ST>, Pg> for Vec<(Bound<T>, Bound<T>)>
where
    T: ToSql<ST, Pg>,
    [(Bound<T>, Bound<T>)]: ToSql<Multirange<ST>, Pg>,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        ToSql::<Multirange<ST>, Pg>::to_sql(self.as_slice(), out)
    }
}

// TODO: nullable impl


Review comment (bug):
It might be worth to convert that into a failable cast via `TryInto`, just to make sure that we don't overflow the u32 here. It might be an edge case, but better be save than sorry. (I really should check the other variable sized `ToSql` impls for such issues, at some point)

Code after:
        (0..len)
            .map(|_| {
                let range_size: usize = bytes.read_i32::<NetworkEndian>()?.try_into()?;
                let (range_bytes, new_bytes) = bytes.split_at(range_size);
                bytes = new_bytes;
                FromSql::from_sql(PgValue::new_internal(range_bytes, &value))
            })
            .collect()
    }
}

#[cfg(feature = "postgres_backend")]
impl<T, ST> ToSql<Multirange<ST>, Pg> for [(Bound<T>, Bound<T>)]
where
    T: ToSql<ST, Pg>,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_u32::<NetworkEndian>(self.len().try_into()?)?;

        let mut buffer = Vec::new();
        for value in self {
            {
                let mut inner_buffer = Output::new(ByteWrapper(&mut buffer), out.metadata_lookup());
                ToSql::<Range<ST>, Pg>::to_sql(&value, &mut inner_buffer)?;
            }
            let buffer_len: i32 = buffer.len().try_into()?;
            out.write_i32::<NetworkEndian>(buffer_len)?;
            out.write_all(&buffer)?;
            buffer.clear();
        }

        Ok(IsNull::No)
    }
}

#[cfg(feature = "postgres_backend")]
impl<T, ST> ToSql<Multirange<ST>, Pg> for Vec<(Bound<T>, Bound<T>)>
where
    T: ToSql<ST, Pg>,
    [(Bound<T>, Bound<T>)]: ToSql<Multirange<ST>, Pg>,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        ToSql::<Multirange<ST>, Pg>::to_sql(self.as_slice(), out)
    }
}

impl<T, ST> ToSql<Nullable<Multirange<ST>>, Pg> for [(Bound<T>, Bound<T>)]
where
    ST: 'static,
    [(Bound<T>, Bound<T>)]: ToSql<ST, Pg>,
    T: ToSql<ST, Pg>,