-
Notifications
You must be signed in to change notification settings - Fork 478
Expand file tree
/
Copy pathcommon.rs
More file actions
187 lines (154 loc) · 4.42 KB
/
common.rs
File metadata and controls
187 lines (154 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2018-2022 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Utilities, types and abstractions common to call and instantiation routines.
use core::marker::PhantomData;
/// Represents a return type.
///
/// Used as a marker type to define the return type of an ink! message in call builders.
#[derive(Debug)]
pub struct ReturnType<T>(PhantomData<fn() -> T>);
impl<T> Clone for ReturnType<T> {
#[inline]
fn clone(&self) -> Self {
Self(Default::default())
}
}
impl<T> Copy for ReturnType<T> {}
impl<T> Default for ReturnType<T> {
#[inline]
fn default() -> Self {
Self(Default::default())
}
}
mod private {
/// Seals the implementation of `ConstructorReturnType`.
pub trait Sealed {}
}
/// Guards against using invalid contract initializer types.
///
/// # Note
///
/// Currently the only allowed types are `()` and `Result<(), E>`
/// where `E` is some unspecified error type.
/// If the contract initializer returns `Result::Err` the utility
/// method that is used to initialize an ink! smart contract will
/// revert the state of the contract instantiation.
pub trait InstantiateResult<C>: private::Sealed {
/// Is `true` if `Self` is `Result<C, E>`.
const IS_RESULT: bool = false;
/// Reflects the output type of the dispatchable ink! constructor.
type Output;
/// The error type of the constructor return type.
type Error: scale::Decode;
/// Construct a success value of the `Output` type.
fn ok(value: C) -> Self::Output;
/// Construct an error value of the `Output` type.
fn err(err: Self::Error) -> Self::Output;
}
impl<T> private::Sealed for T {}
impl<C> InstantiateResult<C> for C {
type Output = C;
type Error = ();
fn ok(value: C) -> Self::Output {
value
}
fn err(_err: Self::Error) -> Self::Output {
// todo!
unreachable!()
}
}
impl<C, E> InstantiateResult<C> for core::result::Result<C, E>
where
E: scale::Decode,
{
const IS_RESULT: bool = true;
type Output = core::result::Result<C, E>;
type Error = E;
fn ok(value: C) -> Self::Output {
Ok(value)
}
fn err(err: Self::Error) -> Self::Output {
Err(err)
}
}
/// A parameter that has been set to some value.
#[derive(Debug, Copy, Clone)]
pub struct Set<T>(pub T);
impl<T> Set<T> {
/// Returns the set value.
#[inline]
pub fn value(self) -> T {
self.0
}
}
/// A parameter that has not been set, yet.
#[derive(Debug)]
pub struct Unset<T>(PhantomData<fn() -> T>);
impl<T> Clone for Unset<T> {
#[inline]
fn clone(&self) -> Self {
Self(Default::default())
}
}
impl<T> Copy for Unset<T> {}
impl<T> Default for Unset<T> {
#[inline]
fn default() -> Self {
Self(Default::default())
}
}
/// Implemented by [`Set`] and [`Unset`] in order to unwrap their value.
///
/// This is useful in case the use-site does not know if it is working with
/// a set or an unset value generically unwrap it using a closure for fallback.
pub trait Unwrap {
/// The output type of the `unwrap_or_else` operation.
type Output;
/// Returns the set value or evaluates the given closure.
fn unwrap_or_else<F>(self, f: F) -> Self::Output
where
F: FnOnce() -> Self::Output;
}
impl<T> Unwrap for Unset<T> {
type Output = T;
#[inline]
fn unwrap_or_else<F>(self, f: F) -> Self::Output
where
F: FnOnce() -> Self::Output,
{
f()
}
}
impl<T> Unwrap for Set<T> {
type Output = T;
#[inline]
fn unwrap_or_else<F>(self, _: F) -> Self::Output
where
F: FnOnce() -> Self::Output,
{
self.value()
}
}
// #[cfg(test)]
// mod tests {
// use super::*;
//
// #[test]
// fn instantiate_result_types() {
// static_assertions::assert_type_eq_all!(
// Result<(), u8>,
// <Result<(), u8> as InstantiateResult<()>>
// );
// }
// }