cairo_lang_sierra/extensions/modules/
try_from_felt252.rs

1use std::marker::PhantomData;
2
3use super::felt252::Felt252Type;
4use super::range_check::RangeCheckType;
5use crate::extensions::lib_func::{
6    BranchSignature, LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
7    SignatureSpecializationContext,
8};
9use crate::extensions::{
10    NamedType, NoGenericArgsGenericLibfunc, OutputVarReferenceInfo, SpecializationError,
11};
12use crate::ids::GenericTypeId;
13
14/// Trait for implementing try_{ty}_from_felt252.
15pub trait TryFromFelt252: Default {
16    /// The try_{ty}_from_felt252 library function id.
17    const STR_ID: &'static str;
18    /// The id of the generic type to implement the library functions for.
19    const GENERIC_TYPE_ID: GenericTypeId;
20}
21/// Libfunc for attempting to convert a felt252 into a uint.
22#[derive(Default)]
23pub struct TryFromFelt252Libfunc<TTryFromFelt252: TryFromFelt252> {
24    _phantom: PhantomData<TTryFromFelt252>,
25}
26impl<TTryFromFelt252: TryFromFelt252> NoGenericArgsGenericLibfunc
27    for TryFromFelt252Libfunc<TTryFromFelt252>
28{
29    const STR_ID: &'static str = TTryFromFelt252::STR_ID;
30
31    fn specialize_signature(
32        &self,
33        context: &dyn SignatureSpecializationContext,
34    ) -> Result<LibfuncSignature, SpecializationError> {
35        let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
36        let rc_output_info = OutputVarInfo::new_builtin(range_check_type.clone(), 0);
37        Ok(LibfuncSignature {
38            param_signatures: vec![
39                ParamSignature::new(range_check_type).with_allow_add_const(),
40                ParamSignature::new(context.get_concrete_type(Felt252Type::id(), &[])?),
41            ],
42            branch_signatures: vec![
43                // Success.
44                BranchSignature {
45                    vars: vec![rc_output_info.clone(), OutputVarInfo {
46                        ty: context.get_concrete_type(TTryFromFelt252::GENERIC_TYPE_ID, &[])?,
47                        ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 1 },
48                    }],
49                    ap_change: SierraApChange::Known { new_vars_only: false },
50                },
51                // Failure.
52                BranchSignature {
53                    vars: vec![rc_output_info],
54                    ap_change: SierraApChange::Known { new_vars_only: false },
55                },
56            ],
57            fallthrough: Some(0),
58        })
59    }
60}