ergotree_ir/types/
smethod.rs1use crate::serialization::sigma_byte_reader::SigmaByteRead;
2use crate::serialization::sigma_byte_writer::SigmaByteWrite;
3use crate::serialization::types::TypeCode;
4use crate::serialization::SigmaParsingError;
5use std::collections::HashMap;
6use std::convert::TryFrom;
7
8use super::sfunc::SFunc;
9use super::stype::SType;
10use super::stype_companion::STypeCompanion;
11use super::stype_param::STypeVar;
12use super::type_unify::unify_many;
13use super::type_unify::TypeUnificationError;
14use crate::serialization::SigmaParsingError::UnknownMethodId;
15
16#[derive(PartialEq, Eq, Debug, Clone)]
18pub struct MethodId(pub u8);
19
20impl MethodId {
21 pub(crate) fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> std::io::Result<()> {
22 w.put_u8(self.0)
23 }
24
25 pub(crate) fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> std::io::Result<Self> {
26 Ok(Self(r.get_u8()?))
27 }
28}
29
30#[derive(PartialEq, Eq, Debug, Clone)]
32pub struct SMethod {
33 pub obj_type: STypeCompanion,
35 method_raw: SMethodDesc,
36}
37
38impl SMethod {
39 pub const fn new(obj_type: STypeCompanion, method_raw: SMethodDesc) -> SMethod {
41 SMethod {
42 obj_type,
43 method_raw,
44 }
45 }
46
47 pub(crate) fn from_ids(
49 type_id: TypeCode,
50 method_id: MethodId,
51 ) -> Result<Self, SigmaParsingError> {
52 let obj_type = STypeCompanion::try_from(type_id)?;
53 match obj_type.method_by_id(&method_id) {
54 Some(m) => Ok(m),
55 None => Err(UnknownMethodId(method_id, type_id.value())),
56 }
57 }
58
59 pub fn tpe(&self) -> &SFunc {
61 &self.method_raw.tpe
62 }
63
64 pub fn name(&self) -> &'static str {
66 self.method_raw.name
67 }
68
69 pub fn method_id(&self) -> MethodId {
71 self.method_raw.method_id.clone()
72 }
73
74 pub fn with_concrete_types(self, subst: &HashMap<STypeVar, SType>) -> Self {
76 let new_tpe = self.method_raw.tpe.clone().with_subst(subst);
77 Self {
78 method_raw: self.method_raw.with_tpe(new_tpe),
79 ..self
80 }
81 }
82
83 pub fn specialize_for(
86 self,
87 obj_tpe: SType,
88 args: Vec<SType>,
89 ) -> Result<SMethod, TypeUnificationError> {
90 let mut items2 = vec![obj_tpe];
91 let mut args = args;
92 items2.append(args.as_mut());
93 unify_many(self.tpe().t_dom.clone(), items2).map(|subst| self.with_concrete_types(&subst))
94 }
95}
96
97#[derive(PartialEq, Eq, Debug, Clone)]
99pub struct SMethodDesc {
100 pub(crate) name: &'static str,
101 pub(crate) method_id: MethodId,
102 pub(crate) tpe: SFunc,
103}
104
105impl SMethodDesc {
106 pub fn property(
108 obj_tpe: SType,
109 name: &'static str,
110 res_tpe: SType,
111 id: MethodId,
112 ) -> SMethodDesc {
113 SMethodDesc {
114 method_id: id,
115 name,
116 tpe: SFunc {
117 t_dom: vec![obj_tpe],
118 t_range: res_tpe.into(),
119 tpe_params: vec![],
120 },
121 }
122 }
123 pub(crate) fn as_method(&self, obj_type: STypeCompanion) -> SMethod {
124 SMethod {
125 obj_type,
126 method_raw: self.clone(),
127 }
128 }
129
130 pub(crate) fn with_tpe(self, tpe: SFunc) -> Self {
131 Self { tpe, ..self }
132 }
133}