-
Notifications
You must be signed in to change notification settings - Fork 5
/
lib.rs
94 lines (81 loc) · 2.81 KB
/
lib.rs
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
#![no_std]
use demo_walker as walker;
use sails_rs::{cell::RefCell, prelude::*};
mod counter;
mod dog;
mod mammal;
mod ping;
mod references;
mod this_that;
mod value_fee;
// Dog data is stored as a global variable. However, it has exactly the same lifetime
// the Counter data incapsulated in the program itself, i.e. there are no any benefits
// of using a global variable here. It is just a demonstration of how to use global variables.
static mut DOG_DATA: Option<RefCell<walker::WalkerData>> = None;
static mut REF_DATA: u8 = 42;
fn dog_data() -> &'static RefCell<walker::WalkerData> {
unsafe {
DOG_DATA
.as_ref()
.unwrap_or_else(|| panic!("`Dog` data should be initialized first"))
}
}
pub struct DemoProgram {
// Counter data has the same lifetime as the program itself, i.e. it will
// live as long as the program is available on the network.
counter_data: RefCell<counter::CounterData>,
}
#[program]
impl DemoProgram {
#[allow(clippy::should_implement_trait)]
/// Program constructor (called once at the very beginning of the program lifetime)
pub fn default() -> Self {
unsafe {
DOG_DATA = Some(RefCell::new(walker::WalkerData::new(
Default::default(),
Default::default(),
)));
}
Self {
counter_data: RefCell::new(counter::CounterData::new(Default::default())),
}
}
/// Another program constructor (called once at the very beginning of the program lifetime)
pub fn new(counter: Option<u32>, dog_position: Option<(i32, i32)>) -> Self {
unsafe {
let dog_position = dog_position.unwrap_or_default();
DOG_DATA = Some(RefCell::new(walker::WalkerData::new(
dog_position.0,
dog_position.1,
)));
}
Self {
counter_data: RefCell::new(counter::CounterData::new(counter.unwrap_or_default())),
}
}
// Exposing service with overriden route
#[route("ping_pong")]
pub fn ping(&self) -> ping::PingService {
ping::PingService::default()
}
// Exposing another service
pub fn counter(&self) -> counter::CounterService {
counter::CounterService::new(&self.counter_data)
}
// Exposing yet another service
pub fn dog(&self) -> dog::DogService {
dog::DogService::new(walker::WalkerService::new(dog_data()))
}
pub fn references(&self) -> references::ReferenceService {
#[allow(static_mut_refs)]
unsafe {
references::ReferenceService::new(&mut REF_DATA, "demo")
}
}
pub fn this_that(&self) -> this_that::MyService {
this_that::MyService::default()
}
pub fn value_fee(&self) -> value_fee::FeeService {
value_fee::FeeService::new(10_000_000_000_000)
}
}