ic-mops 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mops/base@0.7.4/LICENSE +208 -0
- package/.mops/base@0.7.4/README.md +64 -0
- package/.mops/base@0.7.4/mops.toml +5 -0
- package/.mops/base@0.7.4/src/Array.mo +686 -0
- package/.mops/base@0.7.4/src/AssocList.mo +203 -0
- package/.mops/base@0.7.4/src/Blob.mo +55 -0
- package/.mops/base@0.7.4/src/Bool.mo +44 -0
- package/.mops/base@0.7.4/src/Buffer.mo +1937 -0
- package/.mops/base@0.7.4/src/CertifiedData.mo +29 -0
- package/.mops/base@0.7.4/src/Char.mo +67 -0
- package/.mops/base@0.7.4/src/Debug.mo +15 -0
- package/.mops/base@0.7.4/src/Deque.mo +75 -0
- package/.mops/base@0.7.4/src/Error.mo +41 -0
- package/.mops/base@0.7.4/src/ExperimentalCycles.mo +51 -0
- package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +36 -0
- package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +121 -0
- package/.mops/base@0.7.4/src/Float.mo +150 -0
- package/.mops/base@0.7.4/src/Func.mo +38 -0
- package/.mops/base@0.7.4/src/Hash.mo +83 -0
- package/.mops/base@0.7.4/src/HashMap.mo +229 -0
- package/.mops/base@0.7.4/src/Heap.mo +113 -0
- package/.mops/base@0.7.4/src/Int.mo +150 -0
- package/.mops/base@0.7.4/src/Int16.mo +159 -0
- package/.mops/base@0.7.4/src/Int32.mo +160 -0
- package/.mops/base@0.7.4/src/Int64.mo +161 -0
- package/.mops/base@0.7.4/src/Int8.mo +160 -0
- package/.mops/base@0.7.4/src/Iter.mo +220 -0
- package/.mops/base@0.7.4/src/IterType.mo +7 -0
- package/.mops/base@0.7.4/src/List.mo +433 -0
- package/.mops/base@0.7.4/src/Nat.mo +75 -0
- package/.mops/base@0.7.4/src/Nat16.mo +146 -0
- package/.mops/base@0.7.4/src/Nat32.mo +146 -0
- package/.mops/base@0.7.4/src/Nat64.mo +146 -0
- package/.mops/base@0.7.4/src/Nat8.mo +146 -0
- package/.mops/base@0.7.4/src/None.mo +19 -0
- package/.mops/base@0.7.4/src/Option.mo +160 -0
- package/.mops/base@0.7.4/src/Order.mo +46 -0
- package/.mops/base@0.7.4/src/Prelude.mo +33 -0
- package/.mops/base@0.7.4/src/Principal.mo +58 -0
- package/.mops/base@0.7.4/src/RBTree.mo +218 -0
- package/.mops/base@0.7.4/src/Random.mo +188 -0
- package/.mops/base@0.7.4/src/Result.mo +210 -0
- package/.mops/base@0.7.4/src/Stack.mo +40 -0
- package/.mops/base@0.7.4/src/Text.mo +615 -0
- package/.mops/base@0.7.4/src/Time.mo +37 -0
- package/.mops/base@0.7.4/src/Trie.mo +1200 -0
- package/.mops/base@0.7.4/src/TrieMap.mo +180 -0
- package/.mops/base@0.7.4/src/TrieSet.mo +97 -0
- package/.mops/base@0.8.3/LICENSE +208 -0
- package/.mops/base@0.8.3/README.md +64 -0
- package/.mops/base@0.8.3/mops.toml +6 -0
- package/.mops/base@0.8.3/src/Array.mo +717 -0
- package/.mops/base@0.8.3/src/AssocList.mo +404 -0
- package/.mops/base@0.8.3/src/Blob.mo +212 -0
- package/.mops/base@0.8.3/src/Bool.mo +44 -0
- package/.mops/base@0.8.3/src/Buffer.mo +2660 -0
- package/.mops/base@0.8.3/src/CertifiedData.mo +53 -0
- package/.mops/base@0.8.3/src/Char.mo +65 -0
- package/.mops/base@0.8.3/src/Debug.mo +56 -0
- package/.mops/base@0.8.3/src/Deque.mo +243 -0
- package/.mops/base@0.8.3/src/Error.mo +68 -0
- package/.mops/base@0.8.3/src/ExperimentalCycles.mo +151 -0
- package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +60 -0
- package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +348 -0
- package/.mops/base@0.8.3/src/Float.mo +843 -0
- package/.mops/base@0.8.3/src/Func.mo +46 -0
- package/.mops/base@0.8.3/src/Hash.mo +82 -0
- package/.mops/base@0.8.3/src/HashMap.mo +457 -0
- package/.mops/base@0.8.3/src/Heap.mo +233 -0
- package/.mops/base@0.8.3/src/Int.mo +365 -0
- package/.mops/base@0.8.3/src/Int16.mo +521 -0
- package/.mops/base@0.8.3/src/Int32.mo +522 -0
- package/.mops/base@0.8.3/src/Int64.mo +522 -0
- package/.mops/base@0.8.3/src/Int8.mo +522 -0
- package/.mops/base@0.8.3/src/Iter.mo +227 -0
- package/.mops/base@0.8.3/src/IterType.mo +7 -0
- package/.mops/base@0.8.3/src/List.mo +930 -0
- package/.mops/base@0.8.3/src/Nat.mo +305 -0
- package/.mops/base@0.8.3/src/Nat16.mo +144 -0
- package/.mops/base@0.8.3/src/Nat32.mo +144 -0
- package/.mops/base@0.8.3/src/Nat64.mo +144 -0
- package/.mops/base@0.8.3/src/Nat8.mo +144 -0
- package/.mops/base@0.8.3/src/None.mo +19 -0
- package/.mops/base@0.8.3/src/Option.mo +154 -0
- package/.mops/base@0.8.3/src/Order.mo +46 -0
- package/.mops/base@0.8.3/src/Prelude.mo +33 -0
- package/.mops/base@0.8.3/src/Principal.mo +249 -0
- package/.mops/base@0.8.3/src/RBTree.mo +681 -0
- package/.mops/base@0.8.3/src/Random.mo +270 -0
- package/.mops/base@0.8.3/src/Result.mo +209 -0
- package/.mops/base@0.8.3/src/Stack.mo +93 -0
- package/.mops/base@0.8.3/src/Text.mo +761 -0
- package/.mops/base@0.8.3/src/Time.mo +36 -0
- package/.mops/base@0.8.3/src/Timer.mo +62 -0
- package/.mops/base@0.8.3/src/Trie.mo +1603 -0
- package/.mops/base@0.8.3/src/TrieMap.mo +392 -0
- package/.mops/base@0.8.3/src/TrieSet.mo +148 -0
- package/mops.js +1 -1
- package/network.txt +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/// Certified data.
|
|
2
|
+
///
|
|
3
|
+
/// The Internet Computer allows canister smart contracts to store a small amount of data during
|
|
4
|
+
/// update method processing so that during query call processing, the canister can obtain
|
|
5
|
+
/// a certificate about that data.
|
|
6
|
+
///
|
|
7
|
+
/// This module provides a _low-level_ interface to this API, aimed at advanced
|
|
8
|
+
/// users and library implementors. See the Internet Computer Functional
|
|
9
|
+
/// Specification and corresponding documentation for how to use this to make query
|
|
10
|
+
/// calls to your canister tamperproof.
|
|
11
|
+
|
|
12
|
+
import Prim "mo:⛔";
|
|
13
|
+
|
|
14
|
+
module {
|
|
15
|
+
|
|
16
|
+
/// Set the certified data.
|
|
17
|
+
///
|
|
18
|
+
/// Must be called from an update method, else traps.
|
|
19
|
+
/// Must be passed a blob of at most 32 bytes, else traps.
|
|
20
|
+
///
|
|
21
|
+
/// Example:
|
|
22
|
+
/// ```motoko no-repl
|
|
23
|
+
/// import CertifiedData "mo:base/CertifiedData";
|
|
24
|
+
/// import Blob "mo:base/Blob";
|
|
25
|
+
///
|
|
26
|
+
/// // Must be in an update call
|
|
27
|
+
///
|
|
28
|
+
/// let array : [Nat8] = [1, 2, 3];
|
|
29
|
+
/// let blob = Blob.fromArray(array);
|
|
30
|
+
/// CertifiedData.set(blob);
|
|
31
|
+
/// ```
|
|
32
|
+
///
|
|
33
|
+
/// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var
|
|
34
|
+
///
|
|
35
|
+
public let set : (data : Blob) -> () = Prim.setCertifiedData;
|
|
36
|
+
|
|
37
|
+
/// Gets a certificate
|
|
38
|
+
///
|
|
39
|
+
/// Returns `null` if no certificate is available, e.g. when processing an
|
|
40
|
+
/// update call or inter-canister call. This returns a non-`null` value only
|
|
41
|
+
/// when processing a query call.
|
|
42
|
+
///
|
|
43
|
+
/// Example:
|
|
44
|
+
/// ```motoko no-repl
|
|
45
|
+
/// import CertifiedData "mo:base/CertifiedData";
|
|
46
|
+
/// // Must be in a query call
|
|
47
|
+
///
|
|
48
|
+
/// CertifiedData.getCertificate();
|
|
49
|
+
/// ```
|
|
50
|
+
/// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var
|
|
51
|
+
///
|
|
52
|
+
public let getCertificate : () -> ?Blob = Prim.getCertificate;
|
|
53
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/// Characters
|
|
2
|
+
import Prim "mo:⛔";
|
|
3
|
+
module {
|
|
4
|
+
|
|
5
|
+
/// Characters represented as Unicode code points.
|
|
6
|
+
public type Char = Prim.Types.Char;
|
|
7
|
+
|
|
8
|
+
/// Convert character `c` to a word containing its Unicode scalar value.
|
|
9
|
+
public let toNat32 : (c : Char) -> Nat32 = Prim.charToNat32;
|
|
10
|
+
|
|
11
|
+
/// Convert `w` to a character.
|
|
12
|
+
/// Traps if `w` is not a valid Unicode scalar value.
|
|
13
|
+
/// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.
|
|
14
|
+
public let fromNat32 : (w : Nat32) -> Char = Prim.nat32ToChar;
|
|
15
|
+
|
|
16
|
+
/// Convert character `c` to single character text.
|
|
17
|
+
public let toText : (c : Char) -> Text = Prim.charToText;
|
|
18
|
+
|
|
19
|
+
// Not exposed pending multi-char implementation.
|
|
20
|
+
private let toUpper : (c : Char) -> Char = Prim.charToUpper;
|
|
21
|
+
|
|
22
|
+
// Not exposed pending multi-char implementation.
|
|
23
|
+
private let toLower : (c : Char) -> Char = Prim.charToLower;
|
|
24
|
+
|
|
25
|
+
/// Returns `true` when `c` is a decimal digit between `0` and `9`, otherwise `false`.
|
|
26
|
+
public func isDigit(c : Char) : Bool {
|
|
27
|
+
Prim.charToNat32(c) -% Prim.charToNat32('0') <= (9 : Nat32)
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/// Returns the Unicode _White_Space_ property of `c`.
|
|
31
|
+
public let isWhitespace : (c : Char) -> Bool = Prim.charIsWhitespace;
|
|
32
|
+
|
|
33
|
+
/// Returns the Unicode _Lowercase_ property of `c`.
|
|
34
|
+
public let isLowercase : (c : Char) -> Bool = Prim.charIsLowercase;
|
|
35
|
+
|
|
36
|
+
/// Returns the Unicode _Uppercase_ property of `c`.
|
|
37
|
+
public let isUppercase : (c : Char) -> Bool = Prim.charIsUppercase;
|
|
38
|
+
|
|
39
|
+
/// Returns the Unicode _Alphabetic_ property of `c`.
|
|
40
|
+
public let isAlphabetic : (c : Char) -> Bool = Prim.charIsAlphabetic;
|
|
41
|
+
|
|
42
|
+
/// Returns `x == y`.
|
|
43
|
+
public func equal(x : Char, y : Char) : Bool { x == y };
|
|
44
|
+
|
|
45
|
+
/// Returns `x != y`.
|
|
46
|
+
public func notEqual(x : Char, y : Char) : Bool { x != y };
|
|
47
|
+
|
|
48
|
+
/// Returns `x < y`.
|
|
49
|
+
public func less(x : Char, y : Char) : Bool { x < y };
|
|
50
|
+
|
|
51
|
+
/// Returns `x <= y`.
|
|
52
|
+
public func lessOrEqual(x : Char, y : Char) : Bool { x <= y };
|
|
53
|
+
|
|
54
|
+
/// Returns `x > y`.
|
|
55
|
+
public func greater(x : Char, y : Char) : Bool { x > y };
|
|
56
|
+
|
|
57
|
+
/// Returns `x >= y`.
|
|
58
|
+
public func greaterOrEqual(x : Char, y : Char) : Bool { x >= y };
|
|
59
|
+
|
|
60
|
+
/// Returns the order of `x` and `y`.
|
|
61
|
+
public func compare(x : Char, y : Char) : { #less; #equal; #greater } {
|
|
62
|
+
if (x < y) { #less } else if (x == y) { #equal } else { #greater }
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/// Utility functions for debugging.
|
|
2
|
+
///
|
|
3
|
+
/// Import from the base library to use this module.
|
|
4
|
+
/// ```motoko name=import
|
|
5
|
+
/// import Debug "mo:base/Debug";
|
|
6
|
+
/// ```
|
|
7
|
+
|
|
8
|
+
import Prim "mo:⛔";
|
|
9
|
+
module {
|
|
10
|
+
/// Prints `text` to output stream.
|
|
11
|
+
///
|
|
12
|
+
/// NOTE: The output is placed in the replica log. When running on mainnet,
|
|
13
|
+
/// this function has no effect.
|
|
14
|
+
///
|
|
15
|
+
/// ```motoko include=import
|
|
16
|
+
/// Debug.print "Hello New World!";
|
|
17
|
+
/// Debug.print(debug_show(4)) // Often used with `debug_show` to convert values to Text
|
|
18
|
+
/// ```
|
|
19
|
+
public func print(text : Text) {
|
|
20
|
+
Prim.debugPrint text
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/// `trap(t)` traps execution with a user-provided diagnostic message.
|
|
24
|
+
///
|
|
25
|
+
/// The caller of a future whose execution called `trap(t)` will
|
|
26
|
+
/// observe the trap as an `Error` value, thrown at `await`, with code
|
|
27
|
+
/// `#canister_error` and message `m`. Here `m` is a more descriptive `Text`
|
|
28
|
+
/// message derived from the provided `t`. See example for more details.
|
|
29
|
+
///
|
|
30
|
+
/// NOTE: Other execution environments that cannot handle traps may only
|
|
31
|
+
/// propagate the trap and terminate execution, with or without some
|
|
32
|
+
/// descriptive message.
|
|
33
|
+
///
|
|
34
|
+
/// ```motoko
|
|
35
|
+
/// import Debug "mo:base/Debug";
|
|
36
|
+
/// import Error "mo:base/Error";
|
|
37
|
+
///
|
|
38
|
+
/// actor {
|
|
39
|
+
/// func fail() : async () {
|
|
40
|
+
/// Debug.trap("user provided error message");
|
|
41
|
+
/// };
|
|
42
|
+
///
|
|
43
|
+
/// public func foo() : async () {
|
|
44
|
+
/// try {
|
|
45
|
+
/// await fail();
|
|
46
|
+
/// } catch e {
|
|
47
|
+
/// let code = Error.code(e); // evaluates to #canister_error
|
|
48
|
+
/// let message = Error.message(e); // contains user provided error message
|
|
49
|
+
/// }
|
|
50
|
+
/// };
|
|
51
|
+
/// }
|
|
52
|
+
/// ```
|
|
53
|
+
public func trap(errorMessage : Text) : None {
|
|
54
|
+
Prim.trap errorMessage
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/// Double-ended queue (deque) of a generic element type `T`.
|
|
2
|
+
///
|
|
3
|
+
/// The interface to deques is purely functional, not imperative, and deques are immutable values.
|
|
4
|
+
/// In particular, deque operations such as push and pop do not update their input deque but, instead, return the
|
|
5
|
+
/// value of the modified deque, alongside any other data.
|
|
6
|
+
/// The input deque is left unchanged.
|
|
7
|
+
///
|
|
8
|
+
/// Examples of use-cases:
|
|
9
|
+
/// Queue (FIFO) by using `pushBack()` and `popFront()`.
|
|
10
|
+
/// Stack (LIFO) by using `pushFront()` and `popFront()`.
|
|
11
|
+
///
|
|
12
|
+
/// A deque is internally implemented as two lists, a head access list and a (reversed) tail access list,
|
|
13
|
+
/// that are dynamically size-balanced by splitting.
|
|
14
|
+
///
|
|
15
|
+
/// Construction: Create a new deque with the `empty<T>()` function.
|
|
16
|
+
///
|
|
17
|
+
/// Note on the costs of push and pop functions:
|
|
18
|
+
/// * Runtime: `O(1) amortized costs, `O(n)` worst case cost per single call.
|
|
19
|
+
/// * Space: `O(1) amortized costs, `O(n)` worst case cost per single call.
|
|
20
|
+
///
|
|
21
|
+
/// `n` denotes the number of elements stored in the deque.
|
|
22
|
+
|
|
23
|
+
import List "List";
|
|
24
|
+
import P "Prelude";
|
|
25
|
+
|
|
26
|
+
module {
|
|
27
|
+
type List<T> = List.List<T>;
|
|
28
|
+
|
|
29
|
+
/// Double-ended queue (deque) data type.
|
|
30
|
+
public type Deque<T> = (List<T>, List<T>);
|
|
31
|
+
|
|
32
|
+
/// Create a new empty deque.
|
|
33
|
+
///
|
|
34
|
+
/// Example:
|
|
35
|
+
/// ```motoko
|
|
36
|
+
/// import Deque "mo:base/Deque";
|
|
37
|
+
///
|
|
38
|
+
/// Deque.empty<Nat>()
|
|
39
|
+
/// ```
|
|
40
|
+
///
|
|
41
|
+
/// Runtime: `O(1)`.
|
|
42
|
+
///
|
|
43
|
+
/// Space: `O(1)`.
|
|
44
|
+
public func empty<T>() : Deque<T> { (List.nil(), List.nil()) };
|
|
45
|
+
|
|
46
|
+
/// Determine whether a deque is empty.
|
|
47
|
+
/// Returns true if `deque` is empty, otherwise `false`.
|
|
48
|
+
///
|
|
49
|
+
/// Example:
|
|
50
|
+
/// ```motoko
|
|
51
|
+
/// import Deque "mo:base/Deque";
|
|
52
|
+
///
|
|
53
|
+
/// let deque = Deque.empty<Nat>();
|
|
54
|
+
/// Deque.isEmpty(deque) // => true
|
|
55
|
+
/// ```
|
|
56
|
+
///
|
|
57
|
+
/// Runtime: `O(1)`.
|
|
58
|
+
///
|
|
59
|
+
/// Space: `O(1)`.
|
|
60
|
+
public func isEmpty<T>(deque : Deque<T>) : Bool {
|
|
61
|
+
switch deque {
|
|
62
|
+
case (f, r) { List.isNil(f) and List.isNil(r) }
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
func check<T>(q : Deque<T>) : Deque<T> {
|
|
67
|
+
switch q {
|
|
68
|
+
case (null, r) {
|
|
69
|
+
let (a, b) = List.split(List.size(r) / 2, r);
|
|
70
|
+
(List.reverse(b), a)
|
|
71
|
+
};
|
|
72
|
+
case (f, null) {
|
|
73
|
+
let (a, b) = List.split(List.size(f) / 2, f);
|
|
74
|
+
(a, List.reverse(b))
|
|
75
|
+
};
|
|
76
|
+
case q { q }
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/// Insert a new element on the front end of a deque.
|
|
81
|
+
/// Returns the new deque with `element` in the front followed by the elements of `deque`.
|
|
82
|
+
///
|
|
83
|
+
/// This may involve dynamic rebalancing of the two, internally used lists.
|
|
84
|
+
///
|
|
85
|
+
/// Example:
|
|
86
|
+
/// ```motoko
|
|
87
|
+
/// import Deque "mo:base/Deque";
|
|
88
|
+
///
|
|
89
|
+
/// Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1) // deque with elements [1, 2]
|
|
90
|
+
/// ```
|
|
91
|
+
///
|
|
92
|
+
/// Runtime: `O(n)` worst-case, amortized to `O(1)`.
|
|
93
|
+
///
|
|
94
|
+
/// Space: `O(n)` worst-case, amortized to `O(1)`.
|
|
95
|
+
///
|
|
96
|
+
/// `n` denotes the number of elements stored in the deque.
|
|
97
|
+
public func pushFront<T>(deque : Deque<T>, element : T) : Deque<T> {
|
|
98
|
+
check(List.push(element, deque.0), deque.1)
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/// Inspect the optional element on the front end of a deque.
|
|
102
|
+
/// Returns `null` if `deque` is empty. Otherwise, the front element of `deque`.
|
|
103
|
+
///
|
|
104
|
+
/// Example:
|
|
105
|
+
/// ```motoko
|
|
106
|
+
/// import Deque "mo:base/Deque";
|
|
107
|
+
///
|
|
108
|
+
/// let deque = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);
|
|
109
|
+
/// Deque.peekFront(deque) // => ?1
|
|
110
|
+
/// ```
|
|
111
|
+
///
|
|
112
|
+
/// Runtime: `O(1)`.
|
|
113
|
+
///
|
|
114
|
+
/// Space: `O(1)`.
|
|
115
|
+
///
|
|
116
|
+
public func peekFront<T>(deque : Deque<T>) : ?T {
|
|
117
|
+
switch deque {
|
|
118
|
+
case (?(x, f), r) { ?x };
|
|
119
|
+
case (null, ?(x, r)) { ?x };
|
|
120
|
+
case _ { null }
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/// Remove the element on the front end of a deque.
|
|
125
|
+
/// Returns `null` if `deque` is empty. Otherwise, it returns a pair of
|
|
126
|
+
/// the first element and a new deque that contains all the remaining elements of `deque`.
|
|
127
|
+
///
|
|
128
|
+
/// This may involve dynamic rebalancing of the two, internally used lists.
|
|
129
|
+
///
|
|
130
|
+
/// Example:
|
|
131
|
+
/// ```motoko
|
|
132
|
+
/// import Deque "mo:base/Deque";
|
|
133
|
+
/// import Debug "mo:base/Debug";
|
|
134
|
+
/// let initial = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);
|
|
135
|
+
/// // initial deque with elements [1, 2]
|
|
136
|
+
/// let reduced = Deque.popFront(initial);
|
|
137
|
+
/// switch reduced {
|
|
138
|
+
/// case null {
|
|
139
|
+
/// Debug.trap "Empty queue impossible"
|
|
140
|
+
/// };
|
|
141
|
+
/// case (?result) {
|
|
142
|
+
/// let removedElement = result.0; // 1
|
|
143
|
+
/// let reducedDeque = result.1; // deque with element [2].
|
|
144
|
+
/// }
|
|
145
|
+
/// }
|
|
146
|
+
/// ```
|
|
147
|
+
///
|
|
148
|
+
/// Runtime: `O(n)` worst-case, amortized to `O(1)`.
|
|
149
|
+
///
|
|
150
|
+
/// Space: `O(n)` worst-case, amortized to `O(1)`.
|
|
151
|
+
///
|
|
152
|
+
/// `n` denotes the number of elements stored in the deque.
|
|
153
|
+
public func popFront<T>(deque : Deque<T>) : ?(T, Deque<T>) {
|
|
154
|
+
switch deque {
|
|
155
|
+
case (?(x, f), r) { ?(x, check(f, r)) };
|
|
156
|
+
case (null, ?(x, r)) { ?(x, check(null, r)) };
|
|
157
|
+
case _ { null }
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/// Insert a new element on the back end of a deque.
|
|
162
|
+
/// Returns the new deque with all the elements of `deque`, followed by `element` on the back.
|
|
163
|
+
///
|
|
164
|
+
/// This may involve dynamic rebalancing of the two, internally used lists.
|
|
165
|
+
///
|
|
166
|
+
/// Example:
|
|
167
|
+
/// ```motoko
|
|
168
|
+
/// import Deque "mo:base/Deque";
|
|
169
|
+
///
|
|
170
|
+
/// Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2) // deque with elements [1, 2]
|
|
171
|
+
/// ```
|
|
172
|
+
///
|
|
173
|
+
/// Runtime: `O(n)` worst-case, amortized to `O(1)`.
|
|
174
|
+
///
|
|
175
|
+
/// Space: `O(n)` worst-case, amortized to `O(1)`.
|
|
176
|
+
///
|
|
177
|
+
/// `n` denotes the number of elements stored in the deque.
|
|
178
|
+
public func pushBack<T>(deque : Deque<T>, element : T) : Deque<T> {
|
|
179
|
+
check(deque.0, List.push(element, deque.1))
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/// Inspect the optional element on the back end of a deque.
|
|
183
|
+
/// Returns `null` if `deque` is empty. Otherwise, the back element of `deque`.
|
|
184
|
+
///
|
|
185
|
+
/// Example:
|
|
186
|
+
/// ```motoko
|
|
187
|
+
/// import Deque "mo:base/Deque";
|
|
188
|
+
///
|
|
189
|
+
/// let deque = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);
|
|
190
|
+
/// Deque.peekBack(deque) // => ?2
|
|
191
|
+
/// ```
|
|
192
|
+
///
|
|
193
|
+
/// Runtime: `O(1)`.
|
|
194
|
+
///
|
|
195
|
+
/// Space: `O(1)`.
|
|
196
|
+
///
|
|
197
|
+
public func peekBack<T>(deque : Deque<T>) : ?T {
|
|
198
|
+
switch deque {
|
|
199
|
+
case (f, ?(x, r)) { ?x };
|
|
200
|
+
case (?(x, r), null) { ?x };
|
|
201
|
+
case _ { null }
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/// Remove the element on the back end of a deque.
|
|
206
|
+
/// Returns `null` if `deque` is empty. Otherwise, it returns a pair of
|
|
207
|
+
/// a new deque that contains the remaining elements of `deque`
|
|
208
|
+
/// and, as the second pair item, the removed back element.
|
|
209
|
+
///
|
|
210
|
+
/// This may involve dynamic rebalancing of the two, internally used lists.
|
|
211
|
+
///
|
|
212
|
+
/// Example:
|
|
213
|
+
/// ```motoko
|
|
214
|
+
/// import Deque "mo:base/Deque";
|
|
215
|
+
/// import Debug "mo:base/Debug";
|
|
216
|
+
///
|
|
217
|
+
/// let initial = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);
|
|
218
|
+
/// // initial deque with elements [1, 2]
|
|
219
|
+
/// let reduced = Deque.popBack(initial);
|
|
220
|
+
/// switch reduced {
|
|
221
|
+
/// case null {
|
|
222
|
+
/// Debug.trap "Empty queue impossible"
|
|
223
|
+
/// };
|
|
224
|
+
/// case (?result) {
|
|
225
|
+
/// let reducedDeque = result.0; // deque with element [1].
|
|
226
|
+
/// let removedElement = result.1; // 2
|
|
227
|
+
/// }
|
|
228
|
+
/// }
|
|
229
|
+
/// ```
|
|
230
|
+
///
|
|
231
|
+
/// Runtime: `O(n)` worst-case, amortized to `O(1)`.
|
|
232
|
+
///
|
|
233
|
+
/// Space: `O(n)` worst-case, amortized to `O(1)`.
|
|
234
|
+
///
|
|
235
|
+
/// `n` denotes the number of elements stored in the deque.
|
|
236
|
+
public func popBack<T>(deque : Deque<T>) : ?(Deque<T>, T) {
|
|
237
|
+
switch deque {
|
|
238
|
+
case (f, ?(x, r)) { ?(check(f, r), x) };
|
|
239
|
+
case (?(x, f), null) { ?(check(f, null), x) };
|
|
240
|
+
case _ { null }
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/// Error values and inspection.
|
|
2
|
+
///
|
|
3
|
+
/// The `Error` type is the argument to `throw`, parameter of `catch`.
|
|
4
|
+
/// The `Error` type is opaque.
|
|
5
|
+
|
|
6
|
+
import Prim "mo:⛔";
|
|
7
|
+
|
|
8
|
+
module {
|
|
9
|
+
|
|
10
|
+
/// Error value resulting from `async` computations
|
|
11
|
+
public type Error = Prim.Types.Error;
|
|
12
|
+
|
|
13
|
+
/// Error code to classify different kinds of user and system errors:
|
|
14
|
+
/// ```motoko
|
|
15
|
+
/// type ErrorCode = {
|
|
16
|
+
/// // Fatal error.
|
|
17
|
+
/// #system_fatal;
|
|
18
|
+
/// // Transient error.
|
|
19
|
+
/// #system_transient;
|
|
20
|
+
/// // Destination invalid.
|
|
21
|
+
/// #destination_invalid;
|
|
22
|
+
/// // Explicit reject by canister code.
|
|
23
|
+
/// #canister_reject;
|
|
24
|
+
/// // Canister trapped.
|
|
25
|
+
/// #canister_error;
|
|
26
|
+
/// // Future error code (with unrecognized numeric code).
|
|
27
|
+
/// #future : Nat32;
|
|
28
|
+
/// // Error issuing inter-canister call
|
|
29
|
+
/// // (indicating destination queue full or freezing threshold crossed).
|
|
30
|
+
/// #call_error : { err_code : Nat32 }
|
|
31
|
+
/// };
|
|
32
|
+
/// ```
|
|
33
|
+
public type ErrorCode = Prim.ErrorCode;
|
|
34
|
+
|
|
35
|
+
/// Create an error from the message with the code `#canister_reject`.
|
|
36
|
+
///
|
|
37
|
+
/// Example:
|
|
38
|
+
/// ```motoko
|
|
39
|
+
/// import Error "mo:base/Error";
|
|
40
|
+
///
|
|
41
|
+
/// Error.reject("Example error") // can be used as throw argument
|
|
42
|
+
/// ```
|
|
43
|
+
public let reject : (message : Text) -> Error = Prim.error;
|
|
44
|
+
|
|
45
|
+
/// Returns the code of an error.
|
|
46
|
+
///
|
|
47
|
+
/// Example:
|
|
48
|
+
/// ```motoko
|
|
49
|
+
/// import Error "mo:base/Error";
|
|
50
|
+
///
|
|
51
|
+
/// let error = Error.reject("Example error");
|
|
52
|
+
/// Error.code(error) // #canister_reject
|
|
53
|
+
/// ```
|
|
54
|
+
public let code : (error : Error) -> ErrorCode = Prim.errorCode;
|
|
55
|
+
|
|
56
|
+
/// Returns the message of an error.
|
|
57
|
+
///
|
|
58
|
+
/// Example:
|
|
59
|
+
/// ```motoko
|
|
60
|
+
/// import Error "mo:base/Error";
|
|
61
|
+
/// import Debug "mo:base/Debug";
|
|
62
|
+
///
|
|
63
|
+
/// let error = Error.reject("Example error");
|
|
64
|
+
/// Error.message(error) // "Example error"
|
|
65
|
+
/// ```
|
|
66
|
+
public let message : (error : Error) -> Text = Prim.errorMessage;
|
|
67
|
+
|
|
68
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/// Managing cycles within actors on the Internet Computer (IC).
|
|
2
|
+
///
|
|
3
|
+
/// The usage of the Internet Computer is measured, and paid for, in _cycles_.
|
|
4
|
+
/// This library provides imperative operations for observing cycles, transferring cycles, and
|
|
5
|
+
/// observing refunds of cycles.
|
|
6
|
+
///
|
|
7
|
+
/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.
|
|
8
|
+
/// Dedicated syntactic support for manipulating cycles may be added to the language in future, obsoleting this library.
|
|
9
|
+
///
|
|
10
|
+
/// **NOTE:** Since cycles measure computational resources, the value of `balance()` can change from one call to the next.
|
|
11
|
+
///
|
|
12
|
+
/// Example for use on IC:
|
|
13
|
+
/// ```motoko no-repl
|
|
14
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
15
|
+
/// import Debug "mo:base/Debug";
|
|
16
|
+
///
|
|
17
|
+
/// actor {
|
|
18
|
+
/// public func main() : async() {
|
|
19
|
+
/// Debug.print("Main balance: " # debug_show(Cycles.balance()));
|
|
20
|
+
/// Cycles.add(15_000_000);
|
|
21
|
+
/// await operation(); // accepts 10_000_000 cycles
|
|
22
|
+
/// Debug.print("Main refunded: " # debug_show(Cycles.refunded())); // 5_000_000
|
|
23
|
+
/// Debug.print("Main balance: " # debug_show(Cycles.balance())); // decreased by around 10_000_000
|
|
24
|
+
/// };
|
|
25
|
+
///
|
|
26
|
+
/// func operation() : async() {
|
|
27
|
+
/// Debug.print("Operation balance: " # debug_show(Cycles.balance()));
|
|
28
|
+
/// Debug.print("Operation available: " # debug_show(Cycles.available()));
|
|
29
|
+
/// let obtained = Cycles.accept(10_000_000);
|
|
30
|
+
/// Debug.print("Operation obtained: " # debug_show(obtained)); // => 10_000_000
|
|
31
|
+
/// Debug.print("Operation balance: " # debug_show(Cycles.balance())); // increased by 10_000_000
|
|
32
|
+
/// Debug.print("Operation available: " # debug_show(Cycles.available())); // decreased by 10_000_000
|
|
33
|
+
/// }
|
|
34
|
+
/// }
|
|
35
|
+
/// ```
|
|
36
|
+
import Prim "mo:⛔";
|
|
37
|
+
module {
|
|
38
|
+
|
|
39
|
+
/// Returns the actor's current balance of cycles as `amount`.
|
|
40
|
+
///
|
|
41
|
+
/// Example for use on the IC:
|
|
42
|
+
/// ```motoko no-repl
|
|
43
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
44
|
+
/// import Debug "mo:base/Debug";
|
|
45
|
+
///
|
|
46
|
+
/// actor {
|
|
47
|
+
/// public func main() : async() {
|
|
48
|
+
/// let balance = Cycles.balance();
|
|
49
|
+
/// Debug.print("Balance: " # debug_show(balance));
|
|
50
|
+
/// }
|
|
51
|
+
/// }
|
|
52
|
+
/// ```
|
|
53
|
+
public let balance : () -> (amount : Nat) = Prim.cyclesBalance;
|
|
54
|
+
|
|
55
|
+
/// Returns the currently available `amount` of cycles.
|
|
56
|
+
/// The amount available is the amount received in the current call,
|
|
57
|
+
/// minus the cumulative amount `accept`ed by this call.
|
|
58
|
+
/// On exit from the current shared function or async expression via `return` or `throw`,
|
|
59
|
+
/// any remaining available amount is automatically refunded to the caller/context.
|
|
60
|
+
///
|
|
61
|
+
/// Example for use on the IC:
|
|
62
|
+
/// ```motoko no-repl
|
|
63
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
64
|
+
/// import Debug "mo:base/Debug";
|
|
65
|
+
///
|
|
66
|
+
/// actor {
|
|
67
|
+
/// public func main() : async() {
|
|
68
|
+
/// let available = Cycles.available();
|
|
69
|
+
/// Debug.print("Available: " # debug_show(available));
|
|
70
|
+
/// }
|
|
71
|
+
/// }
|
|
72
|
+
/// ```
|
|
73
|
+
public let available : () -> (amount : Nat) = Prim.cyclesAvailable;
|
|
74
|
+
|
|
75
|
+
/// Transfers up to `amount` from `available()` to `balance()`.
|
|
76
|
+
/// Returns the amount actually transferred, which may be less than
|
|
77
|
+
/// requested, for example, if less is available, or if canister balance limits are reached.
|
|
78
|
+
///
|
|
79
|
+
/// Example for use on the IC (for simplicity, only transferring cycles to itself):
|
|
80
|
+
/// ```motoko no-repl
|
|
81
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
82
|
+
/// import Debug "mo:base/Debug";
|
|
83
|
+
///
|
|
84
|
+
/// actor {
|
|
85
|
+
/// public func main() : async() {
|
|
86
|
+
/// Cycles.add(15_000_000);
|
|
87
|
+
/// await operation(); // accepts 10_000_000 cycles
|
|
88
|
+
/// };
|
|
89
|
+
///
|
|
90
|
+
/// func operation() : async() {
|
|
91
|
+
/// let obtained = Cycles.accept(10_000_000);
|
|
92
|
+
/// Debug.print("Obtained: " # debug_show(obtained)); // => 10_000_000
|
|
93
|
+
/// }
|
|
94
|
+
/// }
|
|
95
|
+
/// ```
|
|
96
|
+
public let accept : (amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;
|
|
97
|
+
|
|
98
|
+
/// Indicates additional `amount` of cycles to be transferred in
|
|
99
|
+
/// the next call, that is, evaluation of a shared function call or
|
|
100
|
+
/// async expression.
|
|
101
|
+
/// Traps if the current total would exceed `2 ** 128` cycles.
|
|
102
|
+
/// Upon the call, but not before, the total amount of cycles ``add``ed since
|
|
103
|
+
/// the last call is deducted from `balance()`.
|
|
104
|
+
/// If this total exceeds `balance()`, the caller traps, aborting the call.
|
|
105
|
+
///
|
|
106
|
+
/// **Note**: The implicit register of added amounts is reset to zero on entry to
|
|
107
|
+
/// a shared function and after each shared function call or resume from an await.
|
|
108
|
+
///
|
|
109
|
+
/// Example for use on the IC (for simplicity, only transferring cycles to itself):
|
|
110
|
+
/// ```motoko no-repl
|
|
111
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
112
|
+
///
|
|
113
|
+
/// actor {
|
|
114
|
+
/// func operation() : async() {
|
|
115
|
+
/// ignore Cycles.accept(10_000_000);
|
|
116
|
+
/// };
|
|
117
|
+
///
|
|
118
|
+
/// public func main() : async() {
|
|
119
|
+
/// Cycles.add(15_000_000);
|
|
120
|
+
/// await operation();
|
|
121
|
+
/// }
|
|
122
|
+
/// }
|
|
123
|
+
/// ```
|
|
124
|
+
public let add : (amount : Nat) -> () = Prim.cyclesAdd;
|
|
125
|
+
|
|
126
|
+
/// Reports `amount` of cycles refunded in the last `await` of the current
|
|
127
|
+
/// context, or zero if no await has occurred yet.
|
|
128
|
+
/// Calling `refunded()` is solely informational and does not affect `balance()`.
|
|
129
|
+
/// Instead, refunds are automatically added to the current balance,
|
|
130
|
+
/// whether or not `refunded` is used to observe them.
|
|
131
|
+
///
|
|
132
|
+
/// Example for use on the IC (for simplicity, only transferring cycles to itself):
|
|
133
|
+
/// ```motoko no-repl
|
|
134
|
+
/// import Cycles "mo:base/ExperimentalCycles";
|
|
135
|
+
/// import Debug "mo:base/Debug";
|
|
136
|
+
///
|
|
137
|
+
/// actor {
|
|
138
|
+
/// func operation() : async() {
|
|
139
|
+
/// ignore Cycles.accept(10_000_000);
|
|
140
|
+
/// };
|
|
141
|
+
///
|
|
142
|
+
/// public func main() : async() {
|
|
143
|
+
/// Cycles.add(15_000_000);
|
|
144
|
+
/// await operation(); // accepts 10_000_000 cycles
|
|
145
|
+
/// Debug.print("Refunded: " # debug_show(Cycles.refunded())); // 5_000_000
|
|
146
|
+
/// }
|
|
147
|
+
/// }
|
|
148
|
+
/// ```
|
|
149
|
+
public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;
|
|
150
|
+
|
|
151
|
+
}
|