1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
1617use fluence::fce;
1819use fluence_it_types::IValue;
20use serde::Deserialize;
21use serde::Serialize;
2223pub const STEPPER_SUCCESS: i32 = 0;
2425/// Describes a result returned at the end of the stepper execution.
26#[fce]
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28pub struct StepperOutcome {
29/// A return code, where STEPPER_SUCCESS means success.
30pub ret_code: i32,
3132/// Contains error message if ret_code != STEPPER_SUCCESS.
33pub error_message: String,
3435/// Contains script data that should be preserved in an executor of this stepper
36 /// regardless of ret_code value.
37pub data: Vec<u8>,
3839/// Public keys of peers that should receive data.
40pub next_peer_pks: Vec<String>,
41}
4243impl StepperOutcome {
44pub fn from_ivalues(mut ivalues: Vec<IValue>) -> Result<Self, String> {
45const OUTCOME_FIELDS_COUNT: usize = 4;
4647let record_values = match ivalues.remove(0) {
48 IValue::Record(record_values) => record_values,
49 v => return Err(format!("expected record for StepperOutcome, got {:?}", v)),
50 };
5152let mut record_values = record_values.into_vec();
53if record_values.len() != OUTCOME_FIELDS_COUNT {
54return Err(format!(
55"expected StepperOutcome struct with {} fields, got {:?}",
56 OUTCOME_FIELDS_COUNT, record_values
57 ));
58 }
5960let ret_code = match record_values.remove(0) {
61 IValue::S32(ret_code) => ret_code,
62 v => return Err(format!("expected i32 for ret_code, got {:?}", v)),
63 };
6465let error_message = match record_values.remove(0) {
66 IValue::String(str) => str,
67 v => return Err(format!("expected string for data, got {:?}", v)),
68 };
6970let data = match record_values.remove(0) {
71 IValue::Array(array) => {
72let array: Result<Vec<_>, _> = array
73 .into_iter()
74 .map(|v| match v {
75 IValue::U8(byte) => Ok(byte),
76 v => Err(format!("expected a byte, got {:?}", v)),
77 })
78 .collect();
79 array?
80}
81 v => return Err(format!("expected Vec<u8> for data, got {:?}", v)),
82 };
8384let next_peer_pks = match record_values.remove(0) {
85 IValue::Array(ar_values) => {
86let array = ar_values
87 .into_iter()
88 .map(|v| match v {
89 IValue::String(str) => Ok(str),
90 v => Err(format!("expected string for next_peer_pks, got {:?}", v)),
91 })
92 .collect::<Result<Vec<String>, _>>()?;
9394Ok(array)
95 }
96 v => Err(format!("expected array for next_peer_pks, got {:?}", v)),
97 }?;
9899let outcome = Self {
100 ret_code,
101 error_message,
102 data,
103 next_peer_pks,
104 };
105106Ok(outcome)
107 }
108}