cairo_lang_sierra/extensions/modules/
coupon.rs1use super::function_call::SignatureAndFunctionConcreteLibfunc;
2use crate::define_libfunc_hierarchy;
3use crate::extensions::lib_func::{
4 LibfuncSignature, OutputVarInfo, SierraApChange, SignatureSpecializationContext,
5};
6use crate::extensions::type_specialization_context::TypeSpecializationContext;
7use crate::extensions::types::TypeInfo;
8use crate::extensions::{
9 ConcreteType, NamedLibfunc, NamedType, OutputVarReferenceInfo, SpecializationError,
10 args_as_single_type, args_as_single_user_func,
11};
12use crate::ids::{ConcreteTypeId, FunctionId, GenericTypeId};
13use crate::program::GenericArg;
14
15#[derive(Default)]
20pub struct CouponType {}
21
22impl NamedType for CouponType {
23 type Concrete = CouponConcreteType;
24 const ID: GenericTypeId = GenericTypeId::new_inline("Coupon");
25
26 fn specialize(
27 &self,
28 _context: &dyn TypeSpecializationContext,
29 args: &[GenericArg],
30 ) -> Result<Self::Concrete, SpecializationError> {
31 let function_id = args_as_single_user_func(args)?;
32 let long_id = Self::concrete_type_long_id(args);
33 Ok(Self::Concrete {
34 info: TypeInfo {
35 long_id,
36 duplicatable: false,
37 droppable: true,
38 storable: true,
39 zero_sized: true,
40 },
41 function_id,
42 })
43 }
44}
45
46pub fn coupon_ty(
48 context: &dyn SignatureSpecializationContext,
49 function_id: FunctionId,
50) -> Result<ConcreteTypeId, SpecializationError> {
51 context.get_concrete_type(CouponType::id(), &[GenericArg::UserFunc(function_id)])
52}
53
54pub struct CouponConcreteType {
56 pub info: TypeInfo,
57 pub function_id: FunctionId,
58}
59impl ConcreteType for CouponConcreteType {
60 fn info(&self) -> &TypeInfo {
61 &self.info
62 }
63}
64
65define_libfunc_hierarchy! {
66 pub enum CouponLibfunc {
67 Buy(CouponBuyLibfunc),
68 Refund(CouponRefundLibfunc),
69 }, CouponConcreteLibfunc
70}
71
72#[derive(Default)]
78pub struct CouponBuyLibfunc {}
79impl NamedLibfunc for CouponBuyLibfunc {
80 type Concrete = SignatureAndFunctionConcreteLibfunc;
81 const STR_ID: &'static str = "coupon_buy";
82
83 fn specialize_signature(
84 &self,
85 context: &dyn SignatureSpecializationContext,
86 args: &[GenericArg],
87 ) -> Result<LibfuncSignature, SpecializationError> {
88 let coupon_ty = args_as_single_type(args)?;
89 if context.get_type_info(coupon_ty.clone())?.long_id.generic_id != CouponType::id() {
90 return Err(SpecializationError::UnsupportedGenericArg);
91 }
92
93 Ok(LibfuncSignature::new_non_branch(
94 vec![],
95 vec![OutputVarInfo { ty: coupon_ty, ref_info: OutputVarReferenceInfo::ZeroSized }],
96 SierraApChange::Known { new_vars_only: true },
97 ))
98 }
99
100 fn specialize(
101 &self,
102 context: &dyn crate::extensions::lib_func::SpecializationContext,
103 args: &[GenericArg],
104 ) -> Result<Self::Concrete, SpecializationError> {
105 let coupon_ty = args_as_single_type(args)?;
106 let long_id = context.get_type_info(coupon_ty.clone())?.long_id;
107 if long_id.generic_id != CouponType::id() {
108 return Err(SpecializationError::UnsupportedGenericArg);
109 }
110
111 let function_id = args_as_single_user_func(&long_id.generic_args)?;
112
113 Ok(SignatureAndFunctionConcreteLibfunc {
114 function: context.get_function(&function_id)?,
115 signature: self.specialize_signature(context.upcast(), args)?,
116 })
117 }
118}
119
120#[derive(Default)]
123pub struct CouponRefundLibfunc {}
124impl NamedLibfunc for CouponRefundLibfunc {
125 type Concrete = SignatureAndFunctionConcreteLibfunc;
126 const STR_ID: &'static str = "coupon_refund";
127
128 fn specialize_signature(
129 &self,
130 context: &dyn SignatureSpecializationContext,
131 args: &[GenericArg],
132 ) -> Result<LibfuncSignature, SpecializationError> {
133 let coupon_ty = args_as_single_type(args)?;
134 if context.get_type_info(coupon_ty.clone())?.long_id.generic_id != CouponType::id() {
135 return Err(SpecializationError::UnsupportedGenericArg);
136 }
137
138 Ok(LibfuncSignature::new_non_branch(vec![coupon_ty], vec![], SierraApChange::Known {
139 new_vars_only: true,
140 }))
141 }
142
143 fn specialize(
144 &self,
145 context: &dyn crate::extensions::lib_func::SpecializationContext,
146 args: &[GenericArg],
147 ) -> Result<Self::Concrete, SpecializationError> {
148 let coupon_ty = args_as_single_type(args)?;
149 let long_id = context.get_type_info(coupon_ty.clone())?.long_id;
150 if long_id.generic_id != CouponType::id() {
151 return Err(SpecializationError::UnsupportedGenericArg);
152 }
153
154 let function_id = args_as_single_user_func(&long_id.generic_args)?;
155
156 Ok(SignatureAndFunctionConcreteLibfunc {
157 function: context.get_function(&function_id)?,
158 signature: self.specialize_signature(context.upcast(), args)?,
159 })
160 }
161}