provekit_noirc_driver 1.0.0-beta.20-alpha.1

Noir compiler driver.
Documentation
/// Create a new `Self` value from the given `T` value
// docs:start:from-trait
pub trait From<T> {
    fn from(input: T) -> Self;
}
// docs:end:from-trait

impl<T> From<T> for T {
    fn from(input: T) -> T {
        input
    }
}

/// Convert a `Self` value into a `T` value
// docs:start:into-trait
pub trait Into<T> {
    fn into(self) -> T;
}

impl<T, U> Into<T> for U
where
    T: From<U>,
{
    fn into(self) -> T {
        T::from(self)
    }
}
// docs:end:into-trait

// docs:start:from-impls
// Unsigned integers

impl From<u8> for u16 {
    fn from(value: u8) -> u16 {
        value as u16
    }
}

impl From<u8> for u32 {
    fn from(value: u8) -> u32 {
        value as u32
    }
}

impl From<u16> for u32 {
    fn from(value: u16) -> u32 {
        value as u32
    }
}

impl From<u8> for u64 {
    fn from(value: u8) -> u64 {
        value as u64
    }
}

impl From<u16> for u64 {
    fn from(value: u16) -> u64 {
        value as u64
    }
}

impl From<u32> for u64 {
    fn from(value: u32) -> u64 {
        value as u64
    }
}

impl From<u8> for u128 {
    fn from(value: u8) -> u128 {
        value as u128
    }
}

impl From<u16> for u128 {
    fn from(value: u16) -> u128 {
        value as u128
    }
}

impl From<u32> for u128 {
    fn from(value: u32) -> u128 {
        value as u128
    }
}
impl From<u64> for u128 {
    fn from(value: u64) -> u128 {
        value as u128
    }
}

impl From<u8> for Field {
    fn from(value: u8) -> Field {
        value as Field
    }
}

impl From<u16> for Field {
    fn from(value: u16) -> Field {
        value as Field
    }
}

impl From<u32> for Field {
    fn from(value: u32) -> Field {
        value as Field
    }
}
impl From<u64> for Field {
    fn from(value: u64) -> Field {
        value as Field
    }
}

impl From<u128> for Field {
    fn from(value: u128) -> Field {
        value as Field
    }
}

// Signed integers

impl From<i8> for i16 {
    fn from(value: i8) -> i16 {
        value as i16
    }
}

impl From<i8> for i32 {
    fn from(value: i8) -> i32 {
        value as i32
    }
}

impl From<i16> for i32 {
    fn from(value: i16) -> i32 {
        value as i32
    }
}

impl From<i8> for i64 {
    fn from(value: i8) -> i64 {
        value as i64
    }
}

impl From<i16> for i64 {
    fn from(value: i16) -> i64 {
        value as i64
    }
}

impl From<i32> for i64 {
    fn from(value: i32) -> i64 {
        value as i64
    }
}

// Booleans
impl From<bool> for u8 {
    fn from(value: bool) -> u8 {
        value as u8
    }
}
impl From<bool> for u16 {
    fn from(value: bool) -> u16 {
        value as u16
    }
}
impl From<bool> for u32 {
    fn from(value: bool) -> u32 {
        value as u32
    }
}
impl From<bool> for u64 {
    fn from(value: bool) -> u64 {
        value as u64
    }
}
impl From<bool> for u128 {
    fn from(value: bool) -> u128 {
        value as u128
    }
}
impl From<bool> for i8 {
    fn from(value: bool) -> i8 {
        value as i8
    }
}
impl From<bool> for i16 {
    fn from(value: bool) -> i16 {
        value as i16
    }
}
impl From<bool> for i32 {
    fn from(value: bool) -> i32 {
        value as i32
    }
}
impl From<bool> for i64 {
    fn from(value: bool) -> i64 {
        value as i64
    }
}
impl From<bool> for Field {
    fn from(value: bool) -> Field {
        value as Field
    }
}
// docs:end:from-impls

/// A generic interface for casting between primitive types,
/// equivalent of using the `as` keyword between values.
///
/// # Example
///
/// ```
/// let x: Field = 1234567890;
/// let y: u8 = x as u8;
/// let z: u8 = x.as_();
/// assert_eq(y, z);
/// ```
pub trait AsPrimitive<T> {
    /// The equivalent of doing `self as T`.
    fn as_(self) -> T;
}

#[generate_as_primitive_impls]
comptime fn generate_as_primitive_impls(_: FunctionDefinition) -> Quoted {
    let types = [
        quote { bool },
        quote { u8 },
        quote { u16 },
        quote { u32 },
        quote { u64 },
        quote { u128 },
        quote { i8 },
        quote { i16 },
        quote { i32 },
        quote { i64 },
    ];

    let mut impls = [].as_vector();
    for type1 in types {
        for type2 in types {
            let body = if type1 == type2 {
                quote { self }
            } else if type1 == quote { bool } {
                quote { self != 0 }
            } else {
                quote { self as $type1 }
            };

            impls = impls.push_back(
                quote {
                impl AsPrimitive<$type1> for $type2 {
                    fn as_(self) -> $type1 {
                        $body
                    }
                }
            },
            );
        }
    }

    let u_types =
        [quote { bool }, quote { u8 }, quote { u16 }, quote { u32 }, quote { u64 }, quote { u128 }];

    for type2 in u_types {
        let body = quote { self as Field };

        impls = impls.push_back(
            quote {
                impl AsPrimitive<Field> for $type2 {
                    fn as_(self) -> Field {
                        $body
                    }
                }
            },
        );
    }

    for type1 in u_types {
        let body = if type1 == quote { bool } {
            quote { self != 0 }
        } else {
            quote { self as $type1 }
        };

        impls = impls.push_back(
            quote {
                impl AsPrimitive<$type1> for Field {
                    fn as_(self) -> $type1 {
                        $body
                    }
                }
            },
        );
    }

    impls.join(quote {})
}