Sketch of Rc JSON value

This commit is contained in:
Ivan Boldyrev 2024-01-29 17:13:17 +01:00
parent ba1686f835
commit c74cdd99f4
55 changed files with 285 additions and 277 deletions

5
Cargo.lock generated
View File

@ -174,6 +174,7 @@ dependencies = [
"air-interpreter-cid",
"air-interpreter-sede",
"air-interpreter-signatures",
"air-interpreter-value",
"air-utils",
"aquavm-air-parser",
"fluence-keypair",
@ -196,6 +197,7 @@ name = "air-interpreter-interface"
version = "0.17.2"
dependencies = [
"air-interpreter-sede",
"air-interpreter-value",
"fluence-it-types",
"marine-call-parameters",
"marine-rs-sdk",
@ -275,6 +277,7 @@ dependencies = [
"air-interpreter-interface",
"air-interpreter-sede",
"air-interpreter-signatures",
"air-interpreter-value",
"aquavm-air",
"avm-interface",
"avm-server",
@ -430,6 +433,7 @@ dependencies = [
"air-interpreter-interface",
"air-interpreter-sede",
"air-interpreter-signatures",
"air-interpreter-value",
"air-lambda-ast",
"air-lambda-parser",
"air-log-targets",
@ -499,6 +503,7 @@ dependencies = [
name = "aquavm-air-parser"
version = "0.11.1"
dependencies = [
"air-interpreter-value",
"air-lambda-ast",
"air-lambda-parser",
"codespan",

View File

@ -22,6 +22,7 @@ air-interpreter-cid = { version = "0.9.0", path = "../crates/air-lib/interpreter
air-interpreter-data = { version = "0.17.0", path = "../crates/air-lib/interpreter-data" }
air-interpreter-sede = { version = "0.1.0", path = "../crates/air-lib/interpreter-sede" }
air-interpreter-signatures = { version = "0.1.7", path = "../crates/air-lib/interpreter-signatures", features = ["rkyv"] }
air-interpreter-value = { version = "0.1.0", path = "../crates/air-lib/interpreter-value" }
air-interpreter-interface = { version = "0.17.2", path = "../crates/air-lib/interpreter-interface", default-features = false }
air-log-targets = { version = "0.1.0", path = "../crates/air-lib/log-targets" }
air-lambda-ast = { version = "0.1.0", path = "../crates/air-lib/lambda/ast" }

View File

@ -69,7 +69,7 @@ pub enum CatchableError {
/// This error type is produced by a fail instruction.
#[error("fail with '{error}' is used without corresponding xor")]
UserError { error: Rc<JValue> },
UserError { error: JValue },
/// An error occurred while trying to apply lambda to a value.
#[error(transparent)]

View File

@ -69,7 +69,7 @@ impl ExecutionCidState {
pub fn track_service_result(
&mut self,
value: Rc<JValue>,
value: JValue,
tetraplet: RcSecurityTetraplet,
argument_hash: Rc<str>,
) -> Result<CID<ServiceResultCidAggregate>, UncatchableError> {
@ -97,7 +97,7 @@ impl ExecutionCidState {
.map_err(UncatchableError::from)
}
pub(crate) fn get_value_by_cid(&self, cid: &CID<RawValue>) -> Result<Rc<JValue>, UncatchableError> {
pub(crate) fn get_value_by_cid(&self, cid: &CID<RawValue>) -> Result<JValue, UncatchableError> {
self.value_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.get_inner()))
@ -168,7 +168,7 @@ impl ExecutionCidState {
}
pub(crate) struct ResolvedServiceInfo {
pub(crate) value: Rc<JValue>,
pub(crate) value: JValue,
pub(crate) tetraplet: RcSecurityTetraplet,
pub(crate) service_result_aggregate: Rc<ServiceResultCidAggregate>,
}

View File

@ -24,8 +24,6 @@ use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use crate::ToErrorCode;
use std::rc::Rc;
pub(crate) fn get_instruction_error_from_exec_error(
error: &(impl ErrorAffectable + ToErrorCode + ToString),
instruction: &str,
@ -57,11 +55,11 @@ pub(crate) fn get_instruction_error_from_ingredients(
Some(peer_id) => error_from_raw_fields_w_peerid(error_code, error_message, instruction, peer_id),
None => error_from_raw_fields(error_code, error_message, instruction),
};
get_instruction_error_from_error_object(Rc::new(error_object), tetraplet, provenance)
get_instruction_error_from_error_object(error_object, tetraplet, provenance)
}
pub(crate) fn get_instruction_error_from_error_object(
error: Rc<JValue>,
error: JValue,
tetraplet: Option<RcSecurityTetraplet>,
provenance: Provenance,
) -> InstructionError {

View File

@ -22,8 +22,6 @@ use crate::JValue;
use air_interpreter_data::Provenance;
use serde_json::json;
use std::rc::Rc;
pub const ERROR_CODE_FIELD_NAME: &str = "error_code";
pub const MESSAGE_FIELD_NAME: &str = "message";
pub const INSTRUCTION_FIELD_NAME: &str = "instruction";
@ -39,7 +37,7 @@ pub const NO_ERROR_ERROR_CODE: i64 = 0;
#[derive(Debug, Clone)]
pub struct InstructionError {
/// Error object that represents the last occurred error.
pub error: Rc<JValue>,
pub error: JValue,
/// Tetraplet that identify host where the error occurred.
pub tetraplet: Option<RcSecurityTetraplet>,
@ -64,6 +62,7 @@ pub(crate) fn error_from_raw_fields_w_peerid(
INSTRUCTION_FIELD_NAME: instruction,
PEER_ID_FIELD_NAME: peer_id,
})
.into()
}
pub(crate) fn error_from_raw_fields(error_code: i64, error_message: &str, instruction: &str) -> JValue {
@ -72,6 +71,7 @@ pub(crate) fn error_from_raw_fields(error_code: i64, error_message: &str, instru
MESSAGE_FIELD_NAME: error_message,
INSTRUCTION_FIELD_NAME: instruction,
})
.into()
}
/// Checks that a scalar is a value of an object types that contains at least two fields:
@ -142,11 +142,12 @@ pub fn no_error_object() -> JValue {
ERROR_CODE_FIELD_NAME: NO_ERROR_ERROR_CODE,
MESSAGE_FIELD_NAME: NO_ERROR_MESSAGE,
})
.into()
}
pub fn no_error() -> InstructionError {
InstructionError {
error: Rc::new(no_error_object()),
error: no_error_object(),
tetraplet: None,
provenance: Provenance::literal(),
orig_catchable: None,

View File

@ -23,8 +23,6 @@ use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use crate::ToErrorCode;
use std::rc::Rc;
pub(crate) struct LastErrorDescriptor {
error: InstructionError,
@ -56,7 +54,7 @@ impl LastErrorDescriptor {
pub(crate) fn set_from_error_object(
&mut self,
error: Rc<JValue>,
error: JValue,
tetraplet: Option<RcSecurityTetraplet>,
provenance: Provenance,
) {

View File

@ -89,7 +89,7 @@ pub(crate) struct Scalars<'i> {
pub(crate) canon_streams: ValuesSparseMatrix<CanonStreamWithProvenance>,
pub(crate) canon_maps: ValuesSparseMatrix<CanonStreamMapWithProvenance<'i>>,
pub(crate) canon_maps: ValuesSparseMatrix<CanonStreamMapWithProvenance>,
pub(crate) iterable_variables: HashMap<String, FoldState<'i>>,
}
@ -122,10 +122,10 @@ impl<'i> Scalars<'i> {
/// Returns true if there was a previous value for the provided key on the same
/// fold block.
pub(crate) fn set_canon_map_value<'k: 'i>(
pub(crate) fn set_canon_map_value(
&mut self,
name: impl Into<String>,
value: CanonStreamMapWithProvenance<'k>,
value: CanonStreamMapWithProvenance,
) -> ExecutionResult<bool> {
self.canon_maps.set_value(name, value)
}
@ -172,7 +172,7 @@ impl<'i> Scalars<'i> {
.ok_or_else(|| CatchableError::VariableWasNotInitializedAfterNew(name.to_string()).into())
}
pub(crate) fn get_canon_map(&'i self, name: &str) -> ExecutionResult<&'i CanonStreamMapWithProvenance<'i>> {
pub(crate) fn get_canon_map(&'i self, name: &str) -> ExecutionResult<&'i CanonStreamMapWithProvenance> {
self.canon_maps
.get_value(name)?
.ok_or_else(|| CatchableError::VariableWasNotInitializedAfterNew(name.to_string()).into())

View File

@ -293,8 +293,7 @@ mod test {
let mut scalars = ValuesSparseMatrix::new();
let value = json!(1u64);
let rc_value = Rc::new(value);
let value_aggregate = ValueAggregate::from_literal_result(LiteralAggregate::new(rc_value, "".into(), 1.into()));
let value_aggregate = ValueAggregate::from_literal_result(LiteralAggregate::new(value, "".into(), 1.into()));
let value_1_name = "name_1";
scalars.set_value(value_1_name, value_aggregate.clone()).unwrap();

View File

@ -118,7 +118,7 @@ impl StreamMaps {
pub(crate) fn add_stream_map_value(
&mut self,
key: StreamMapKey<'_>,
key: StreamMapKey,
value_descriptor: StreamMapValueDescriptor<'_>,
) -> ExecutionResult<()> {
let StreamMapValueDescriptor {

View File

@ -17,8 +17,7 @@
use crate::execution_step::ValueAggregate;
use crate::JValue;
use serde::Serialize;
use std::borrow::Cow;
use air_interpreter_value::JsonString;
use std::fmt::Display;
use std::fmt::Formatter;
@ -27,25 +26,25 @@ pub(crate) static KEY_FIELD_NAME: &str = "key";
// TODO refactor the keys so that integer and string
// value domains overlap would become impossible or less harmful.
#[derive(Clone, PartialEq, Debug, Eq, Hash)]
pub(crate) enum StreamMapKey<'value> {
Str(Cow<'value, str>),
pub(crate) enum StreamMapKey {
Str(JsonString),
U64(u64),
I64(i64),
}
impl<'value> StreamMapKey<'value> {
impl StreamMapKey {
pub fn from_value(value: JValue) -> Option<Self> {
match value {
JValue::String(s) => Some(StreamMapKey::Str(Cow::Owned(s))),
JValue::String(s) => Some(StreamMapKey::Str(s)),
JValue::Number(n) if n.is_i64() => Some(StreamMapKey::I64(n.as_i64().unwrap())),
JValue::Number(n) if n.is_u64() => Some(StreamMapKey::U64(n.as_u64().unwrap())),
_ => None,
}
}
pub fn from_value_ref(value: &'value JValue) -> Option<Self> {
pub fn from_value_ref(value: &JValue) -> Option<Self> {
match value {
JValue::String(s) => Some(StreamMapKey::Str(Cow::Borrowed(s.as_str()))),
JValue::String(s) => Some(StreamMapKey::Str(s.clone())),
JValue::Number(n) if n.is_i64() => Some(StreamMapKey::I64(n.as_i64().unwrap())),
JValue::Number(n) if n.is_u64() => Some(StreamMapKey::U64(n.as_u64().unwrap())),
_ => None,
@ -58,25 +57,22 @@ impl<'value> StreamMapKey<'value> {
StreamMapKey::from_value(key)
}
pub(crate) fn into_owned(self) -> StreamMapKey<'static> {
pub(crate) fn to_key(&self) -> JsonString {
match self {
StreamMapKey::Str(s) => {
let s = s.to_string();
StreamMapKey::Str(Cow::Owned(s))
}
StreamMapKey::U64(n) => StreamMapKey::U64(n),
StreamMapKey::I64(n) => StreamMapKey::I64(n),
StreamMapKey::Str(s) => s.clone(),
StreamMapKey::U64(n) => format!("{n}").into(),
StreamMapKey::I64(n) => format!("{n}").into(),
}
}
}
impl From<i64> for StreamMapKey<'_> {
impl From<i64> for StreamMapKey {
fn from(value: i64) -> Self {
StreamMapKey::I64(value)
}
}
impl From<u64> for StreamMapKey<'_> {
impl From<u64> for StreamMapKey {
fn from(value: u64) -> Self {
StreamMapKey::U64(value)
}
@ -85,40 +81,37 @@ impl From<u64> for StreamMapKey<'_> {
// TODO unify all types.
// This conversion is used to cast from numeric lambda accessor that leverages u32
// however larpop parser grammar uses i64 for numeric keys inserting into a stream map.
impl From<u32> for StreamMapKey<'_> {
impl From<u32> for StreamMapKey {
fn from(value: u32) -> Self {
StreamMapKey::I64(value.into())
}
}
impl<'value> From<&'value str> for StreamMapKey<'value> {
fn from(value: &'value str) -> Self {
StreamMapKey::Str(Cow::Borrowed(value))
impl From<&str> for StreamMapKey {
fn from(value: &str) -> Self {
StreamMapKey::Str(value.into())
}
}
impl From<String> for StreamMapKey<'static> {
fn from(value: String) -> Self {
StreamMapKey::Str(Cow::Owned(value))
impl From<JsonString> for StreamMapKey {
fn from(value: JsonString) -> Self {
StreamMapKey::Str(value)
}
}
impl<'value> Serialize for StreamMapKey<'value> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
impl Into<JValue> for StreamMapKey {
fn into(self) -> JValue {
match self {
StreamMapKey::Str(s) => serializer.serialize_str(s),
StreamMapKey::U64(n) => serializer.serialize_u64(*n),
StreamMapKey::I64(n) => serializer.serialize_i64(*n),
StreamMapKey::Str(s) => JValue::String(s),
StreamMapKey::U64(n) => n.into(),
StreamMapKey::I64(n) => n.into(),
}
}
}
// This trait impl proposefully prints numbers the same way as strings
// to use it in map-to-scalar cast.
impl<'value> Display for StreamMapKey<'value> {
impl Display for StreamMapKey {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StreamMapKey::Str(s) => write!(f, "{}", s),

View File

@ -34,8 +34,6 @@ use air_parser::ast;
use air_parser::ast::Ap;
use air_trace_handler::merger::MergerApResult;
use std::rc::Rc;
impl<'i> super::ExecutableInstruction<'i> for Ap<'i> {
#[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))]
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {

View File

@ -61,7 +61,7 @@ fn apply_const(
exec_ctx: &ExecutionCtx<'_>,
trace_ctx: &TraceHandler,
) -> ExecutionResult<ValueAggregate> {
let value = Rc::new(value.into());
let value = value.into();
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let value = ValueAggregate::from_literal_result(LiteralAggregate::new(
@ -78,7 +78,6 @@ fn apply_error<'ctx>(
trace_ctx: &TraceHandler,
) -> ExecutionResult<ValueAggregate> {
let (value, mut tetraplets, provenance) = instruction_error.resolve(exec_ctx)?;
let value = Rc::new(value);
// removing is safe because prepare_last_error always returns a vec with one element.
let tetraplet = tetraplets.remove(0);
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
@ -93,7 +92,6 @@ fn apply_last_error<'i>(
trace_ctx: &TraceHandler,
) -> ExecutionResult<ValueAggregate> {
let (value, mut tetraplets, provenance) = error_accessor.resolve(exec_ctx)?;
let value = Rc::new(value);
// removing is safe because prepare_last_error always returns a vec with one element.
let tetraplet = tetraplets.remove(0);
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
@ -134,7 +132,7 @@ fn apply_scalar_wl(
) -> ExecutionResult<ValueAggregate> {
let (value, mut tetraplets, provenance) = ast_scalar.resolve(exec_ctx)?;
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let result = ValueAggregate::new(Rc::new(value), tetraplets.remove(0), position, provenance);
let result = ValueAggregate::new(value, tetraplets.remove(0), position, provenance);
Ok(result)
}
@ -148,11 +146,11 @@ fn apply_canon_stream(
use crate::execution_step::value_types::JValuable;
let canon_stream = exec_ctx.scalars.get_canon_stream(ast_stream.name)?;
let value = JValuable::as_jvalue(&&canon_stream.canon_stream).into_owned();
let value = JValuable::as_jvalue(&&canon_stream.canon_stream);
let tetraplet = canon_stream.tetraplet().clone();
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let value = CanonResultAggregate::new(
Rc::new(value),
value,
tetraplet.peer_pk.as_str().into(),
&tetraplet.json_path,
position,
@ -179,7 +177,7 @@ fn apply_canon_stream_wl(
)?;
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let result = ValueAggregate::new(result.into_owned().into(), tetraplet.into(), position, provenance);
let result = ValueAggregate::new(result, tetraplet.into(), position, provenance);
Ok(result)
}
@ -191,11 +189,11 @@ fn apply_canon_stream_map(
use crate::execution_step::value_types::JValuable;
let canon_stream_map = exec_ctx.scalars.get_canon_map(ast_canon_stream_map.name)?;
let value = JValuable::as_jvalue(&&canon_stream_map.canon_stream_map).into_owned();
let value = JValuable::as_jvalue(&&canon_stream_map.canon_stream_map);
let tetraplet = canon_stream_map.tetraplet();
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let value = CanonResultAggregate::new(
Rc::new(value),
value,
tetraplet.peer_pk.as_str().into(),
&tetraplet.json_path,
position,
@ -220,6 +218,6 @@ fn apply_canon_stream_map_wl(
JValuable::apply_lambda_with_tetraplets(&canon_stream_map, lambda, exec_ctx, &Provenance::canon(cid))?;
let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?;
let result = ValueAggregate::new(result.into_owned().into(), tetraplet.into(), position, provenance);
let result = ValueAggregate::new(result, tetraplet.into(), position, provenance);
Ok(result)
}

View File

@ -61,7 +61,7 @@ fn to_merger_ap_map_result(instr: &impl ToString, trace_ctx: &mut TraceHandler)
}
fn populate_context<'ctx>(
key: StreamMapKey<'ctx>,
key: StreamMapKey,
ap_map_result: &StreamMap<'ctx>,
merger_ap_result: &MergerApResult,
result: ValueAggregate,
@ -75,7 +75,7 @@ fn resolve_key_if_needed<'ctx>(
key: &StreamMapKeyClause<'ctx>,
exec_ctx: &ExecutionCtx<'ctx>,
map_name: &str,
) -> Result<StreamMapKey<'ctx>, ExecutionError> {
) -> Result<StreamMapKey, ExecutionError> {
match key {
&StreamMapKeyClause::Literal(s) => Ok(s.into()),
StreamMapKeyClause::Int(i) => Ok(i.to_owned().into()),
@ -89,7 +89,7 @@ fn resolve<'ctx>(
resolvable: &impl Resolvable,
exec_ctx: &ExecutionCtx<'_>,
map_name: &str,
) -> Result<StreamMapKey<'ctx>, ExecutionError> {
) -> Result<StreamMapKey, ExecutionError> {
let (value, _, _) = resolvable.resolve(exec_ctx)?;
StreamMapKey::from_value(value).ok_or(CatchableError::StreamMapError(unsupported_map_key_type(map_name)).into())
}

View File

@ -65,7 +65,7 @@ pub(crate) fn populate_context_from_peer_service_result<'i>(
Ok(CallResult::executed_stream_stub(service_result_agg_cid))
}
CallOutputValue::None => {
let value_cid = value_to_json_cid(&*executed_result.result).map_err(UncatchableError::from)?;
let value_cid = value_to_json_cid(&executed_result.result).map_err(UncatchableError::from)?;
Ok(CallResult::executed_unused(value_cid))
}

View File

@ -68,7 +68,8 @@ pub(super) fn handle_prev_state<'i>(
)?;
let call_service_failed: CallServiceFailed =
serde_json::from_value((*err_value).clone()).map_err(UncatchableError::MalformedCallServiceFailed)?;
serde_json::from_value(serde_json::to_value(&err_value).expect("TODO"))
.map_err(UncatchableError::MalformedCallServiceFailed)?;
exec_ctx.make_subgraph_incomplete();
exec_ctx.record_call_cid(&tetraplet.peer_pk, failed_cid);
@ -212,9 +213,9 @@ fn try_to_service_result(
tetraplet: &RcSecurityTetraplet,
exec_ctx: &mut ExecutionCtx<'_>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<Rc<JValue>> {
) -> ExecutionResult<JValue> {
match serde_json::from_str(&service_result.result) {
Ok(result) => Ok(Rc::new(result)),
Ok(result) => Ok(result),
Err(e) => {
let error_msg = format!(
"call_service result '{service_result}' can't be serialized or deserialized with an error: {e}"

View File

@ -25,6 +25,7 @@ use crate::execution_step::RcSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplets;
use crate::execution_step::UncatchableError;
use crate::trace_to_exec_err;
use crate::JValue;
use crate::SecurityTetraplet;
use air_interpreter_cid::value_to_json_cid;
@ -220,7 +221,7 @@ impl<'i> ResolvedCall<'i> {
}
/// A version of `resolve_args` that supresses joinable errors.
fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<CheckArgsResult<Vec<serde_json::Value>>> {
fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<CheckArgsResult<Vec<JValue>>> {
let fun_result = self.collect_args(exec_ctx);
CheckArgsResult::new(fun_result.map(|values| values.0))
@ -229,7 +230,7 @@ impl<'i> ResolvedCall<'i> {
fn collect_args(
&self,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(Vec<serde_json::Value>, Vec<RcSecurityTetraplets>)> {
) -> ExecutionResult<(Vec<JValue>, Vec<RcSecurityTetraplets>)> {
let function_args = self.function_arg_paths.iter();
let mut call_arguments = Vec::with_capacity(function_args.len());
let mut tetraplets = Vec::with_capacity(function_args.len());

View File

@ -85,7 +85,7 @@ pub(crate) fn resolve_to_string<'i>(
fn try_jvalue_to_string(jvalue: JValue, variable_name: impl Into<String>) -> ExecutionResult<String> {
match jvalue {
JValue::String(s) => Ok(s),
JValue::String(s) => Ok(s.to_string()),
_ => Err(CatchableError::NonStringValueInTripletResolution {
variable_name: variable_name.into(),
actual_value: jvalue,

View File

@ -114,10 +114,10 @@ fn create_canon_stream_producer<'closure, 'name: 'closure>(
let value = stream_map
.iter_unique_key_object()
.collect::<serde_json::Map<String, JValue>>();
.collect();
let value = ValueAggregate::from_literal_result(LiteralAggregate::new(
Rc::new(value.into()),
JValue::Object(Rc::new(value)),
peer_pk.as_str().into(),
0.into(),
));

View File

@ -57,7 +57,7 @@ fn fail_with_scalar<'i>(scalar: &ast::Scalar<'i>, exec_ctx: &mut ExecutionCtx<'i
let tetraplet = tetraplet.remove(0);
check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?;
fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplet), provenance)
fail_with_error_object(exec_ctx, value, Some(tetraplet), provenance)
}
fn fail_with_scalar_wl<'i>(scalar: &ast::ScalarWithLambda<'i>, exec_ctx: &mut ExecutionCtx<'i>) -> ExecutionResult<()> {
@ -66,7 +66,7 @@ fn fail_with_scalar_wl<'i>(scalar: &ast::ScalarWithLambda<'i>, exec_ctx: &mut Ex
let tetraplet = tetraplet.remove(0);
check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?;
fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplet), provenance)
fail_with_error_object(exec_ctx, value, Some(tetraplet), provenance)
}
fn fail_with_literals(
@ -87,7 +87,7 @@ fn fail_with_literals(
// in (fail x y), x and y are always literals
let provenance = Provenance::literal();
fail_with_error_object(exec_ctx, Rc::new(error_object), Some(literal_tetraplet), provenance)
fail_with_error_object(exec_ctx, error_object, Some(literal_tetraplet), provenance)
}
fn fail_with_canon_stream(
@ -99,7 +99,7 @@ fn fail_with_canon_stream(
// tetraplets always have one element here and it'll be refactored after boxed value
check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?;
fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplets.remove(0)), provenance)
fail_with_error_object(exec_ctx, value, Some(tetraplets.remove(0)), provenance)
}
fn fail_with_last_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> {
@ -147,7 +147,7 @@ fn fail_with_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> {
fn fail_with_error_object(
exec_ctx: &mut ExecutionCtx<'_>,
error: Rc<JValue>,
error: JValue,
tetraplet: Option<RcSecurityTetraplet>,
provenance: Provenance,
) -> ExecutionResult<()> {

View File

@ -26,7 +26,6 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use air_parser::ast;
use std::borrow::Cow;
use std::ops::Deref;
use std::rc::Rc;
@ -65,7 +64,7 @@ pub(crate) fn create_scalar_wl_iterable<'ctx>(
ScalarRef::Value(variable) => {
let jvalues = select_by_lambda_from_scalar(variable.get_result(), lambda, exec_ctx)?;
let tetraplet = variable.get_tetraplet().deref().clone();
from_jvalue(jvalues, tetraplet, variable.get_provenance(), lambda)
from_jvalue(&jvalues, tetraplet, variable.get_provenance(), lambda)
}
ScalarRef::IterableValue(fold_state) => {
let iterable_value = fold_state.iterable.peek().unwrap();
@ -73,7 +72,7 @@ pub(crate) fn create_scalar_wl_iterable<'ctx>(
let tetraplet = to_tetraplet(&iterable_value);
let provenance = to_provenance(&iterable_value);
from_jvalue(jvalue, tetraplet, provenance, lambda)
from_jvalue(&jvalue, tetraplet, provenance, lambda)
}
}
}
@ -132,12 +131,12 @@ pub(crate) fn create_canon_stream_map_wl_iterable_value(
// Source canon map tetraplet is used here similar with a scalar with lens processing path.
let jvalues = JValuable::apply_lambda(&canon_stream_map, lambda, exec_ctx)?;
from_jvalue(jvalues, tetraplet, provenance, lambda)
from_jvalue(&jvalues, tetraplet, provenance, lambda)
}
/// Constructs iterable value from resolved call result.
fn from_value(call_result: ValueAggregate, variable_name: &str) -> ExecutionResult<FoldIterableScalar> {
let len = match call_result.get_result().deref() {
let len = match call_result.get_result() {
JValue::Array(array) => {
if array.is_empty() {
// skip fold if array is empty
@ -159,7 +158,7 @@ fn from_value(call_result: ValueAggregate, variable_name: &str) -> ExecutionResu
/// Construct IterableValue from the result and given triplet.
fn from_jvalue(
jvalue: Cow<'_, JValue>,
jvalue: &JValue,
tetraplet: SecurityTetraplet,
provenance: Provenance,
lambda: &LambdaAST<'_>,
@ -167,10 +166,10 @@ fn from_jvalue(
let tetraplet = populate_tetraplet_with_lambda(tetraplet, lambda);
let tetraplet = Rc::new(tetraplet);
let iterable = match jvalue.as_ref() {
let iterable = match jvalue {
JValue::Array(array) => array,
_ => {
return Err(CatchableError::FoldIteratesOverNonArray(jvalue.into_owned(), lambda.to_string()).into());
return Err(CatchableError::FoldIteratesOverNonArray(jvalue.clone(), lambda.to_string()).into());
}
};

View File

@ -28,21 +28,20 @@ use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
use air_interpreter_value::JsonString;
use air_lambda_ast::Functor;
use air_lambda_parser::ValueAccessor;
use non_empty_vec::NonEmpty;
use std::borrow::Cow;
use std::ops::Deref;
use std::rc::Rc;
pub(crate) struct LambdaResult<'value> {
pub(crate) result: Cow<'value, JValue>,
pub(crate) struct LambdaResult {
pub(crate) result: JValue,
pub(crate) tetraplet_idx: Option<usize>,
}
pub(crate) struct MapLensResult<'value> {
pub(crate) result: Cow<'value, JValue>,
pub(crate) struct MapLensResult {
pub(crate) result: JValue,
pub(crate) tetraplet: RcSecurityTetraplet,
}
@ -50,7 +49,7 @@ pub(crate) fn select_by_lambda_from_stream<'value>(
stream: impl ExactSizeIterator<Item = &'value JValue> + 'value,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<LambdaResult<'value>> {
) -> ExecutionResult<LambdaResult> {
match lambda {
LambdaAST::ValuePath(value_path) => select_by_path_from_stream(stream, value_path, exec_ctx),
LambdaAST::Functor(functor) => Ok(select_by_functor_from_stream(stream, functor)),
@ -58,10 +57,10 @@ pub(crate) fn select_by_lambda_from_stream<'value>(
}
pub(crate) fn select_by_lambda_from_canon_map<'value>(
canon_map: &'value CanonStreamMap<'_>,
canon_map: &'value CanonStreamMap,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<MapLensResult<'value>> {
) -> ExecutionResult<MapLensResult> {
match lambda {
LambdaAST::ValuePath(value_path) => select_by_path_from_canon_map(canon_map, value_path, lambda, exec_ctx),
LambdaAST::Functor(functor) => Ok(select_by_functor_from_canon_map(canon_map, exec_ctx, functor)),
@ -72,10 +71,10 @@ pub(crate) fn select_by_lambda_from_scalar<'value>(
value: &'value JValue,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<Cow<'value, JValue>> {
) -> ExecutionResult<JValue> {
match lambda {
LambdaAST::ValuePath(value_path) => select_by_path_from_scalar(value, value_path.iter(), exec_ctx),
LambdaAST::Functor(functor) => select_by_functor_from_scalar(value, functor).map(Cow::Owned),
LambdaAST::Functor(functor) => select_by_functor_from_scalar(value, functor),
}
}
@ -83,7 +82,7 @@ fn select_by_path_from_stream<'value>(
stream: impl ExactSizeIterator<Item = &'value JValue> + 'value,
lambda: &NonEmpty<ValueAccessor<'_>>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<LambdaResult<'value>> {
) -> ExecutionResult<LambdaResult> {
let stream_size = stream.len();
let (idx, body) = split_to_idx(lambda, exec_ctx)?;
@ -98,10 +97,10 @@ fn select_by_path_from_stream<'value>(
}
fn select_by_path_from_canon_map_stream<'value>(
stream: impl ExactSizeIterator<Item = (&'value JValue, RcSecurityTetraplet)> + 'value,
stream: impl ExactSizeIterator<Item = (JValue, RcSecurityTetraplet)> + 'value,
lambda: &NonEmpty<ValueAccessor<'_>>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<MapLensResult<'value>> {
) -> ExecutionResult<MapLensResult> {
let stream_size = stream.len();
let (idx, body) = split_to_idx(lambda, exec_ctx)?;
@ -112,11 +111,10 @@ fn select_by_path_from_canon_map_stream<'value>(
let select_result = if body.is_empty() {
// csm.$.key.[0] case
let result = Cow::Borrowed(value);
MapLensResult::from_cow(result, tetraplet)
MapLensResult::from_cow(value, tetraplet)
} else {
// csm.$.key.[0].attribute case
let result = select_by_path_from_scalar(value, body.iter(), exec_ctx)?;
let result = select_by_path_from_scalar(&value, body.iter(), exec_ctx)?;
let joined = body.iter().map(ToString::to_string).collect::<Vec<_>>().join(".");
let json_path_suffix = format!(".{}", joined);
@ -129,22 +127,22 @@ fn select_by_path_from_canon_map_stream<'value>(
}
fn select_by_path_from_canon_map<'value>(
canon_map: &'value CanonStreamMap<'_>,
canon_map: &'value CanonStreamMap,
lambda: &NonEmpty<ValueAccessor<'_>>,
original_lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<MapLensResult<'value>> {
) -> ExecutionResult<MapLensResult> {
use crate::execution_step::value_types::CanonStream;
let (prefix, body) = lambda.split_first();
// HashMap<'map>::get(key: &'key K) forces key's lifetime 'key to be as good as 'map.
// This variance-derived requirement forces StreamMapKey<'static> here.
// This variance-derived requirement forces StreamMapKey here.
// See https://github.com/rust-lang/rust/issues/80389#issuecomment-752067798
// for the details.
let stream_map_key: StreamMapKey<'_> = match prefix {
let stream_map_key: StreamMapKey = match prefix {
ValueAccessor::ArrayAccess { idx } => (*idx).into(),
ValueAccessor::FieldAccessByName { field_name } => (*field_name).to_owned().into(),
ValueAccessor::FieldAccessByName { field_name } => JsonString::from(*field_name).to_owned().into(),
ValueAccessor::FieldAccessByScalar { scalar_name } => {
let scalar = exec_ctx.scalars.get_value(scalar_name)?;
lambda_to_execution_error!(try_scalar_ref_as_stream_map_key(scalar))?
@ -158,14 +156,14 @@ fn select_by_path_from_canon_map<'value>(
(Ok(body_part), Some(canon_stream)) => {
// csm.$.key... case
let canon_stream_iter = canon_stream.iter().map(|v| (v.get_result().deref(), v.get_tetraplet()));
let canon_stream_iter = canon_stream.iter().map(|v| (v.get_result().clone(), v.get_tetraplet()));
select_by_path_from_canon_map_stream(canon_stream_iter, &body_part, exec_ctx)?
}
(Err(..), Some(canon_stream)) => {
// csm.$.key case
let prefix_with_path = false;
let tetraplet = update_tetraplet_with_path(canon_map.tetraplet(), original_lambda, prefix_with_path);
let value = Cow::Owned(canon_stream.as_jvalue());
let value = canon_stream.as_jvalue();
MapLensResult::from_cow(value, tetraplet)
}
@ -174,7 +172,6 @@ fn select_by_path_from_canon_map<'value>(
let prefix_with_path = false;
let tetraplet = update_tetraplet_with_path(canon_map.tetraplet(), original_lambda, prefix_with_path);
let value = CanonStream::new(vec![], tetraplet.clone()).as_jvalue();
let value = Cow::Owned(value);
MapLensResult::from_cow(value, tetraplet)
}
@ -225,23 +222,23 @@ fn update_tetraplet_with_path(
fn select_by_functor_from_stream<'value>(
stream: impl ExactSizeIterator<Item = &'value JValue> + 'value,
functor: &Functor,
) -> LambdaResult<'value> {
) -> LambdaResult {
match functor {
Functor::Length => {
let result = serde_json::json!(stream.len());
let result = (stream.len()).into();
LambdaResult::from_value(result)
}
}
}
fn select_by_functor_from_canon_map<'value>(
canon_map: &CanonStreamMap<'_>,
fn select_by_functor_from_canon_map(
canon_map: &CanonStreamMap,
exec_ctx: &ExecutionCtx<'_>,
functor: &Functor,
) -> MapLensResult<'value> {
) -> MapLensResult {
match functor {
Functor::Length => {
let result = serde_json::json!(canon_map.len());
let result = (canon_map.len()).into();
MapLensResult::from_value(result, exec_ctx, functor)
}
}
@ -251,7 +248,7 @@ fn select_by_path_from_scalar<'value, 'accessor>(
mut value: &'value JValue,
lambda: impl Iterator<Item = &'accessor ValueAccessor<'accessor>>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<Cow<'value, JValue>> {
) -> ExecutionResult<JValue> {
for accessor in lambda {
match accessor {
ValueAccessor::ArrayAccess { idx } => {
@ -268,7 +265,7 @@ fn select_by_path_from_scalar<'value, 'accessor>(
}
}
Ok(Cow::Borrowed(value))
Ok(value.clone())
}
fn select_by_functor_from_scalar(value: &JValue, functor: &Functor) -> ExecutionResult<JValue> {
@ -280,13 +277,14 @@ fn select_by_functor_from_scalar(value: &JValue, functor: &Functor) -> Execution
ExecutionError::Catchable(Rc::new(CatchableError::LengthFunctorAppliedToNotArray(value.clone())))
})?
.len();
Ok(serde_json::json!(length))
Ok(length.into())
}
}
}
impl<'value> LambdaResult<'value> {
fn from_cow(result: Cow<'value, JValue>, tetraplet_idx: usize) -> Self {
impl<'value> LambdaResult {
// TODO rename
fn from_cow(result: JValue, tetraplet_idx: usize) -> Self {
Self {
result,
tetraplet_idx: Some(tetraplet_idx),
@ -295,17 +293,19 @@ impl<'value> LambdaResult<'value> {
fn from_value(result: JValue) -> Self {
Self {
result: Cow::Owned(result),
result,
tetraplet_idx: None,
}
}
}
impl<'value> MapLensResult<'value> {
fn from_cow(result: Cow<'value, JValue>, tetraplet: RcSecurityTetraplet) -> Self {
impl<'value> MapLensResult {
// TODO rename
fn from_cow(result: JValue, tetraplet: RcSecurityTetraplet) -> Self {
Self { result, tetraplet }
}
// TODO rename
fn from_value(result: JValue, exec_ctx: &ExecutionCtx<'_>, functor: &Functor) -> Self {
let tetraplet = Rc::new(SecurityTetraplet::new(
exec_ctx.run_parameters.current_peer_id.to_string(),
@ -314,7 +314,7 @@ impl<'value> MapLensResult<'value> {
functor.to_string(),
));
Self {
result: Cow::Owned(result),
result,
tetraplet,
}
}

View File

@ -87,16 +87,16 @@ pub(super) fn try_scalar_ref_as_idx(scalar: ScalarRef<'_>) -> LambdaResult<u32>
}
}
pub(super) fn try_scalar_ref_as_stream_map_key(scalar: ScalarRef<'_>) -> LambdaResult<StreamMapKey<'static>> {
pub(super) fn try_scalar_ref_as_stream_map_key(scalar: ScalarRef<'_>) -> LambdaResult<StreamMapKey> {
match scalar {
ScalarRef::Value(map_accessor) => {
let map_accessor = map_accessor.get_result().as_ref();
let map_accessor = map_accessor.get_result();
let map_key = StreamMapKey::from_value_ref(map_accessor).ok_or(
LambdaError::CanonStreamMapAccessorHasInvalidType {
map_accessor: map_accessor.clone(),
},
)?;
Ok(map_key.into_owned())
Ok(map_key)
}
ScalarRef::IterableValue(_map_accessor) => Err(LambdaError::CanonStreamMapAccessorMustNotBeIterable),
}

View File

@ -67,7 +67,7 @@ fn resolve_errors(
instruction_error: &crate::InstructionError,
lens: &Option<LambdaAST<'_>>,
ctx: &ExecutionCtx<'_>,
) -> Result<(serde_json::Value, Vec<Rc<SecurityTetraplet>>, Provenance), crate::ExecutionError> {
) -> Result<(JValue, Vec<Rc<SecurityTetraplet>>, Provenance), crate::ExecutionError> {
use crate::execution_step::InstructionError;
let InstructionError {
@ -78,8 +78,8 @@ fn resolve_errors(
} = instruction_error;
let jvalue = match lens {
Some(error_accessor) => select_by_lambda_from_scalar(error.as_ref(), error_accessor, ctx)?.into_owned(),
None => error.as_ref().clone(),
Some(error_accessor) => select_by_lambda_from_scalar(error, error_accessor, ctx)?,
None => error.clone(),
};
let tetraplets = match tetraplet {
@ -122,7 +122,7 @@ impl Resolvable for ast::CanonStream<'_> {
let value: &dyn JValuable = &&canon.canon_stream;
let tetraplets = value.as_tetraplets();
Ok((
value.as_jvalue().into_owned(),
value.as_jvalue(),
tetraplets,
Provenance::canon(canon.cid.clone()),
))
@ -144,7 +144,7 @@ impl Resolvable for ast::ScalarWithLambda<'_> {
let (value, root_provenance) = ctx.scalars.get_value(self.name)?.into_jvaluable();
let (value, tetraplet, provenance) = value.apply_lambda_with_tetraplets(&self.lambda, ctx, &root_provenance)?;
let tetraplet = Rc::new(tetraplet);
Ok((value.into_owned(), vec![tetraplet], provenance))
Ok((value, vec![tetraplet], provenance))
}
}
@ -155,7 +155,7 @@ impl Resolvable for ast::CanonStreamWithLambda<'_> {
let (value, tetraplet, provenance) =
value.apply_lambda_with_tetraplets(&self.lambda, ctx, &Provenance::canon(canon.cid.clone()))?;
let tetraplet = Rc::new(tetraplet);
Ok((value.into_owned(), vec![tetraplet], provenance))
Ok((value, vec![tetraplet], provenance))
}
}
@ -190,7 +190,7 @@ impl Resolvable for ast::CanonStreamMap<'_> {
let tetraplets = value.as_tetraplets();
let provenance = Provenance::canon(canon_stream_map_with_prov.cid.clone());
Ok((value.as_jvalue().into_owned(), tetraplets, provenance))
Ok((value.as_jvalue(), tetraplets, provenance))
}
}
@ -205,6 +205,6 @@ impl Resolvable for ast::CanonStreamMapWithLambda<'_> {
let tetraplet = Rc::new(tetraplet);
Ok((value.into_owned(), vec![tetraplet], provenance))
Ok((value, vec![tetraplet], provenance))
}
}

View File

@ -57,12 +57,7 @@ impl CanonStream {
}
pub(crate) fn as_jvalue(&self) -> JValue {
// TODO: this clone will be removed after boxed values
let jvalue_array = self
.values
.iter()
.map(|r| r.get_result().deref().clone())
.collect::<Vec<_>>();
let jvalue_array = self.values.iter().map(|r| r.get_result().clone()).collect();
JValue::Array(jvalue_array)
}

View File

@ -27,6 +27,7 @@ use crate::UncatchableError;
use air_interpreter_cid::CID;
use air_interpreter_data::CanonResultCidAggregate;
use air_interpreter_value::JsonString;
use polyplets::SecurityTetraplet;
use std::collections::HashMap;
@ -36,22 +37,22 @@ use std::rc::Rc;
/// Canon stream map is a read-only struct that mimics conventional map.
/// The contents of a map are fixed at a specific peer.
#[derive(Debug, Clone)]
pub struct CanonStreamMap<'key> {
pub struct CanonStreamMap {
/// Contains all key-value pair objects in this form {"key": key, "value": value}.
/// There might be multiple pairs with the same key.
values: Vec<ValueAggregate>,
/// Index access leverages the map that does key to CanonStream mapping.
map: HashMap<StreamMapKey<'key>, CanonStream>,
map: HashMap<StreamMapKey, CanonStream>,
/// ap arg processing leverages this tetraplet
tetraplet: Rc<SecurityTetraplet>,
}
impl<'key> CanonStreamMap<'key> {
impl CanonStreamMap {
// The argument's tetraplet is used to produce canon streams for keys so
// that the produced canon streams share tetraplets with the original canon stream
// rendered by canon instruction.
pub(crate) fn from_canon_stream(canon_stream: CanonStream) -> ExecutionResult<CanonStreamMap<'key>> {
let mut map: HashMap<StreamMapKey<'_>, CanonStream> = HashMap::new();
pub(crate) fn from_canon_stream(canon_stream: CanonStream) -> ExecutionResult<CanonStreamMap> {
let mut map: HashMap<StreamMapKey, CanonStream> = HashMap::new();
let tetraplet = canon_stream.tetraplet().clone();
for kvpair_obj in canon_stream.iter() {
@ -79,8 +80,8 @@ impl<'key> CanonStreamMap<'key> {
}
pub(crate) fn as_jvalue(&self) -> JValue {
let json_map: serde_json::Map<String, JValue> =
self.map.iter().map(|(k, v)| (k.to_string(), v.as_jvalue())).collect();
let json_map: air_interpreter_value::Map<JsonString, JValue> =
self.map.iter().map(|(k, v)| (k.to_key(), v.as_jvalue())).collect();
json_map.into()
}
@ -92,14 +93,14 @@ impl<'key> CanonStreamMap<'key> {
&self.tetraplet
}
pub(crate) fn index<'self_l>(&'self_l self, stream_map_key: &StreamMapKey<'key>) -> Option<&'self_l CanonStream> {
pub(crate) fn index<'self_l>(&'self_l self, stream_map_key: &StreamMapKey) -> Option<&'self_l CanonStream> {
self.map.get(stream_map_key)
}
}
use std::fmt;
impl fmt::Display for CanonStreamMap<'_> {
impl fmt::Display for CanonStreamMap {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[")?;
for (key, canon_stream) in self.map.iter() {
@ -110,19 +111,19 @@ impl fmt::Display for CanonStreamMap<'_> {
}
#[derive(Debug, Clone)]
pub struct CanonStreamMapWithProvenance<'a> {
pub(crate) canon_stream_map: CanonStreamMap<'a>,
pub struct CanonStreamMapWithProvenance {
pub(crate) canon_stream_map: CanonStreamMap,
pub(crate) cid: CID<CanonResultCidAggregate>,
}
impl<'a> CanonStreamMapWithProvenance<'a> {
pub(crate) fn new(canon_stream_map: CanonStreamMap<'a>, cid: CID<CanonResultCidAggregate>) -> Self {
impl CanonStreamMapWithProvenance {
pub(crate) fn new(canon_stream_map: CanonStreamMap, cid: CID<CanonResultCidAggregate>) -> Self {
Self { canon_stream_map, cid }
}
}
impl<'a> Deref for CanonStreamMapWithProvenance<'a> {
type Target = CanonStreamMap<'a>;
impl<'a> Deref for CanonStreamMapWithProvenance {
type Target = CanonStreamMap;
fn deref(&self) -> &Self::Target {
&self.canon_stream_map
@ -146,7 +147,7 @@ fn get_value_from_obj(value_aggregate: &ValueAggregate) -> ExecutionResult<Value
.ok_or(ExecutionError::Uncatchable(UncatchableError::StreamMapKeyError(
ValueFieldIsAbsent,
)))?;
let result = Rc::new(value.clone());
let result = value.clone();
Ok(ValueAggregate::new(result, tetraplet, trace_pos, provenance))
}
@ -164,7 +165,7 @@ mod test {
use std::borrow::Cow;
use std::rc::Rc;
fn create_value_aggregate(value: Rc<JValue>) -> ValueAggregate {
fn create_value_aggregate(value: JValue) -> ValueAggregate {
ValueAggregate::new(
value,
<_>::default(),

View File

@ -32,7 +32,6 @@ use crate::JValue;
use air_interpreter_data::Provenance;
use air_interpreter_data::TracePos;
use std::rc::Rc;
/// This trait represent bidirectional iterator and
/// is used to abstract values used in fold as iterables.
@ -62,7 +61,7 @@ pub(crate) trait Iterable<'ctx> {
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum IterableItem<'ctx> {
RefValue((&'ctx JValue, RcSecurityTetraplet, TracePos, Provenance)),
RcValue((Rc<JValue>, RcSecurityTetraplet, TracePos, Provenance)),
RcValue((JValue, RcSecurityTetraplet, TracePos, Provenance)),
}
impl IterableItem<'_> {
@ -91,7 +90,7 @@ impl IterableItem<'_> {
use IterableItem::*;
let (value, tetraplet, pos, provenance) = match self {
RefValue((value, tetraplet, pos, prov)) => (Rc::new(value.clone()), tetraplet, pos, prov),
RefValue((value, tetraplet, pos, prov)) => (value.clone(), tetraplet, pos, prov),
RcValue(ingredients) => ingredients,
};

View File

@ -21,8 +21,6 @@ use crate::foldable_next;
use crate::foldable_prev;
use crate::JValue;
use std::ops::Deref;
/// Used for iterating over JValue of array type.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct IterableResolvedCall {
@ -60,7 +58,7 @@ impl<'ctx> Iterable<'ctx> for IterableResolvedCall {
let (result, tetraplet, trace_pos) = self.call_result.as_inner_parts();
let provenance = self.call_result.get_provenance();
let jvalue = match &result.deref() {
let jvalue = match &result {
JValue::Array(array) => &array[self.cursor],
_ => unimplemented!("this jvalue is set only by fold instruction, so it must have an array type"),
};
@ -73,7 +71,7 @@ impl<'ctx> Iterable<'ctx> for IterableResolvedCall {
}
fn len(&self) -> usize {
match self.call_result.get_result().deref() {
match self.call_result.get_result() {
JValue::Array(array) => array.len(),
_ => unimplemented!("this jvalue is set only by fold instruction, so it must have an array type"),
}

View File

@ -32,12 +32,11 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
/// Represent a value that could be transform to a JValue with or without tetraplets.
pub(crate) trait JValuable {
/// Applies lambda to the internal value, produces JValue.
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>>;
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue>;
/// Applies lambda to the internal value, produces JValue with tetraplet.
// TODO self should know about own provenance, but it will require
@ -48,10 +47,10 @@ pub(crate) trait JValuable {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
root_provenance: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)>;
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)>;
/// Return internal value as borrowed if it's possible, owned otherwise.
fn as_jvalue(&self) -> Cow<'_, JValue>;
fn as_jvalue(&self) -> JValue;
/// Convert this boxed value to an owned JValue.
fn into_jvalue(self: Box<Self>) -> JValue;

View File

@ -26,12 +26,11 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
use std::ops::Deref;
impl JValuable for &CanonStream {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>> {
let iter = self.iter().map(|v| v.get_result().deref());
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue> {
let iter = self.iter().map(|v| v.get_result());
let select_result = select_by_lambda_from_stream(iter, lambda, exec_ctx)?;
Ok(select_result.result)
@ -42,8 +41,8 @@ impl JValuable for &CanonStream {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
root_provenance: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> {
let iter = self.iter().map(|v| v.get_result().deref());
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> {
let iter = self.iter().map(|v| v.get_result());
let select_result = select_by_lambda_from_stream(iter, lambda, exec_ctx)?;
let (tetraplet, provenance) = match select_result.tetraplet_idx {
@ -69,9 +68,9 @@ impl JValuable for &CanonStream {
Ok((select_result.result, tetraplet, provenance))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
let jvalue = CanonStream::as_jvalue(self);
Cow::Owned(jvalue)
#[inline]
fn as_jvalue(&self) -> JValue {
CanonStream::as_jvalue(self)
}
fn into_jvalue(self: Box<Self>) -> JValue {

View File

@ -27,10 +27,9 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
impl JValuable for &CanonStreamMap<'_> {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>> {
impl JValuable for &CanonStreamMap {
#[inline]
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue> {
let select_result = select_by_lambda_from_canon_map(self, lambda, exec_ctx)?;
Ok(select_result.result)
}
@ -40,18 +39,19 @@ impl JValuable for &CanonStreamMap<'_> {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
root_provenance: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> {
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> {
let MapLensResult { result, tetraplet } = select_by_lambda_from_canon_map(self, lambda, exec_ctx)?;
// Provenance is borrowed from the map.
Ok((result, tetraplet.as_ref().clone(), root_provenance.clone()))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
let jvalue = CanonStreamMap::as_jvalue(self);
Cow::Owned(jvalue)
#[inline]
fn as_jvalue(&self) -> JValue {
CanonStreamMap::as_jvalue(self)
}
#[inline]
fn into_jvalue(self: Box<Self>) -> JValue {
CanonStreamMap::as_jvalue(&self)
}

View File

@ -27,12 +27,9 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
use std::ops::Deref;
impl JValuable for std::cell::Ref<'_, Vec<ValueAggregate>> {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>> {
let stream_iter = self.iter().map(|r| r.get_result().deref());
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue> {
let stream_iter = self.iter().map(|r| r.get_result());
let select_result = select_by_lambda_from_stream(stream_iter, lambda, exec_ctx)?;
Ok(select_result.result)
}
@ -42,8 +39,8 @@ impl JValuable for std::cell::Ref<'_, Vec<ValueAggregate>> {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
root_provenance: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> {
let stream_iter = self.iter().map(|r| r.get_result().deref());
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> {
let stream_iter = self.iter().map(|r| r.get_result());
let select_result = select_by_lambda_from_stream(stream_iter, lambda, exec_ctx)?;
let tetraplet = match select_result.tetraplet_idx {
@ -57,13 +54,13 @@ impl JValuable for std::cell::Ref<'_, Vec<ValueAggregate>> {
Ok((select_result.result, tetraplet, root_provenance.clone()))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
let jvalue_array = self.iter().map(|r| r.get_result().deref().clone()).collect::<Vec<_>>();
Cow::Owned(JValue::Array(jvalue_array))
fn as_jvalue(&self) -> JValue {
let jvalue_array = self.iter().map(|r| r.get_result().clone()).collect();
JValue::Array(jvalue_array)
}
fn into_jvalue(self: Box<Self>) -> JValue {
let jvalue_array = self.iter().map(|r| r.get_result().deref().clone()).collect::<Vec<_>>();
let jvalue_array = self.iter().map(|r| r.get_result().clone()).collect();
JValue::Array(jvalue_array)
}

View File

@ -27,16 +27,13 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
use std::ops::Deref;
impl<'ctx> JValuable for IterableItem<'ctx> {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>> {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue> {
use super::IterableItem::*;
let jvalue = match self {
RefValue((jvalue, ..)) => jvalue,
RcValue((jvalue, ..)) => jvalue.deref(),
RcValue((jvalue, ..)) => jvalue,
};
let selected_value = select_by_lambda_from_scalar(jvalue, lambda, exec_ctx)?;
@ -48,12 +45,12 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
_root_provenance: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> {
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> {
use super::IterableItem::*;
let (jvalue, tetraplet, provenance) = match self {
RefValue((jvalue, tetraplet, _, provenance)) => (*jvalue, tetraplet, provenance),
RcValue((jvalue, tetraplet, _, provenance)) => (jvalue.deref(), tetraplet, provenance),
RcValue((jvalue, tetraplet, _, provenance)) => (jvalue, tetraplet, provenance),
};
let selected_value = select_by_lambda_from_scalar(jvalue, lambda, exec_ctx)?;
@ -62,12 +59,12 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
Ok((selected_value, tetraplet, provenance.clone()))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
fn as_jvalue(&self) -> JValue {
use super::IterableItem::*;
match self {
RefValue((jvalue, ..)) => Cow::Borrowed(jvalue),
RcValue((jvalue, ..)) => Cow::Borrowed(jvalue.deref()),
RefValue((jvalue, ..)) => (*jvalue).clone(),
RcValue((jvalue, ..)) => jvalue.clone(),
}
}
@ -76,7 +73,7 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
match *self {
RefValue((jvalue, ..)) => jvalue.clone(),
RcValue((jvalue, ..)) => jvalue.deref().clone(),
RcValue((jvalue, ..)) => jvalue.clone(),
}
}

View File

@ -27,11 +27,8 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use std::borrow::Cow;
use std::ops::Deref;
impl JValuable for ValueAggregate {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<Cow<'_, JValue>> {
fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult<JValue> {
let selected_value = select_by_lambda_from_scalar(self.get_result(), lambda, exec_ctx)?;
Ok(selected_value)
}
@ -41,19 +38,21 @@ impl JValuable for ValueAggregate {
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'_>,
_root_provenane: &Provenance,
) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> {
) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> {
let selected_value = select_by_lambda_from_scalar(self.get_result(), lambda, exec_ctx)?;
let tetraplet = populate_tetraplet_with_lambda(self.get_tetraplet().as_ref().clone(), lambda);
Ok((selected_value, tetraplet, self.get_provenance()))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
Cow::Borrowed(self.get_result())
#[inline]
fn as_jvalue(&self) -> JValue {
self.get_result().clone()
}
#[inline]
fn into_jvalue(self: Box<Self>) -> JValue {
self.get_result().deref().clone()
self.get_result().clone()
}
fn as_tetraplets(&self) -> RcSecurityTetraplets {

View File

@ -34,8 +34,6 @@ use air_interpreter_data::TracePos;
use serde::Deserialize;
use serde::Serialize;
use std::rc::Rc;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum ValueAggregate {
@ -76,7 +74,7 @@ impl<'i> ScalarRef<'i> {
impl ValueAggregate {
pub(crate) fn new(
result: Rc<JValue>,
result: JValue,
tetraplet: RcSecurityTetraplet,
trace_pos: TracePos,
provenance: Provenance,
@ -127,7 +125,7 @@ impl ValueAggregate {
}
}
pub(crate) fn as_inner_parts(&self) -> (&Rc<JValue>, RcSecurityTetraplet, TracePos) {
pub(crate) fn as_inner_parts(&self) -> (&JValue, RcSecurityTetraplet, TracePos) {
match self {
ValueAggregate::Literal(ref literal) => (&literal.result, literal.get_tetraplet(), literal.trace_pos),
ValueAggregate::ServiceResult {
@ -149,7 +147,7 @@ impl ValueAggregate {
}
}
pub fn get_result(&self) -> &Rc<JValue> {
pub fn get_result(&self) -> &JValue {
match self {
ValueAggregate::Literal(literal) => &literal.result,
ValueAggregate::ServiceResult {

View File

@ -27,7 +27,7 @@ use std::rc::Rc;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
// no lambda here are literal + lambda is literal
pub struct LiteralAggregate {
pub result: Rc<JValue>,
pub result: JValue,
// this Rc is not really shared ATM, as execution passes through the Resolvable needle
pub init_peer_id: Rc<str>,
// TODO #[serde(skip)]
@ -36,7 +36,7 @@ pub struct LiteralAggregate {
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ServiceResultAggregate {
pub result: Rc<JValue>,
pub result: JValue,
pub tetraplet: RcSecurityTetraplet,
// TODO #[serde(skip)]
pub trace_pos: TracePos,
@ -44,7 +44,7 @@ pub struct ServiceResultAggregate {
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct CanonResultAggregate {
pub result: Rc<JValue>,
pub result: JValue,
pub peer_id: Rc<str>,
pub lambda: Rc<str>,
// TODO #[serde(skip)]
@ -52,7 +52,7 @@ pub struct CanonResultAggregate {
}
impl LiteralAggregate {
pub(crate) fn new(result: Rc<JValue>, init_peer_id: Rc<str>, trace_pos: TracePos) -> Self {
pub(crate) fn new(result: JValue, init_peer_id: Rc<str>, trace_pos: TracePos) -> Self {
Self {
result,
init_peer_id,
@ -66,7 +66,7 @@ impl LiteralAggregate {
}
impl ServiceResultAggregate {
pub(crate) fn new(result: Rc<JValue>, tetraplet: RcSecurityTetraplet, trace_pos: TracePos) -> Self {
pub(crate) fn new(result: JValue, tetraplet: RcSecurityTetraplet, trace_pos: TracePos) -> Self {
Self {
result,
tetraplet,
@ -76,7 +76,7 @@ impl ServiceResultAggregate {
}
impl CanonResultAggregate {
pub(crate) fn new(result: Rc<JValue>, peer_id: Rc<str>, lambda: &str, trace_pos: TracePos) -> Self {
pub(crate) fn new(result: JValue, peer_id: Rc<str>, lambda: &str, trace_pos: TracePos) -> Self {
Self {
result,
peer_id,

View File

@ -23,15 +23,17 @@ use crate::execution_step::value_types::TracePosOperate;
use crate::execution_step::ExecutionResult;
use crate::JValue;
use air_interpreter_value::JsonString;
use air_trace_handler::TraceHandler;
use serde_json::json;
use std::rc::Rc;
pub(super) static VALUE_FIELD_NAME: &str = "value";
pub(super) fn from_key_value(key: StreamMapKey<'_>, value: &JValue) -> Rc<JValue> {
Rc::new(json!({ KEY_FIELD_NAME: key, VALUE_FIELD_NAME: value }))
pub(super) fn from_key_value(key: StreamMapKey, value: &JValue) -> JValue {
let map = maplit::hashmap! {
VALUE_FIELD_NAME => value.clone(),
KEY_FIELD_NAME => key.into(),
};
map.into()
}
#[derive(Debug, Default, Clone)]
@ -46,7 +48,7 @@ impl StreamMap {
pub(crate) fn insert(
&mut self,
key: StreamMapKey<'_>,
key: StreamMapKey,
value: &ValueAggregate,
generation: Generation,
) -> ExecutionResult<()> {
@ -72,7 +74,7 @@ impl StreamMap {
self.stream.iter()
}
pub(crate) fn iter_unique_key_object(&self) -> impl Iterator<Item = (String, JValue)> + '_ {
pub(crate) fn iter_unique_key_object(&self) -> impl Iterator<Item = (JsonString, JValue)> + '_ {
use std::collections::HashSet;
let mut met_keys = HashSet::new();
@ -89,17 +91,11 @@ impl StreamMap {
let key = object
.get(KEY_FIELD_NAME)
.and_then(StreamMapKey::from_value_ref)
.and_then(|key| {
if met_keys.insert(key.to_string()) {
Some(key)
} else {
None
}
})?;
.and_then(|key| if met_keys.insert(key.to_key()) { Some(key) } else { None })?;
let value = object.get(VALUE_FIELD_NAME)?.clone();
Some((key.to_string(), value))
Some((key.to_key(), value))
})
}
}
@ -130,9 +126,8 @@ mod test {
use serde_json::json;
use std::borrow::Cow;
use std::rc::Rc;
fn create_value_aggregate(value: Rc<JValue>) -> ValueAggregate {
fn create_value_aggregate(value: JValue) -> ValueAggregate {
ValueAggregate::new(
value,
<_>::default(),
@ -143,8 +138,8 @@ mod test {
fn compare_stream_iter<'value>(
mut iter: impl Iterator<Item = &'value ValueAggregate>,
key: StreamMapKey<'_>,
value: &Rc<JValue>,
key: StreamMapKey,
value: &JValue,
) -> bool {
let actual_value = iter.next().map(|e| e.get_result()).unwrap();
let expected_value = from_key_value(key, value);
@ -284,9 +279,9 @@ mod test {
(0..count)
.map(|id| {
let key = id.to_string();
let value = json!(id);
let value = id.into();
let value = ValueAggregate::new(
Rc::new(value),
value,
<_>::default(),
0.into(),
air_interpreter_data::Provenance::literal(),

View File

@ -80,6 +80,6 @@ pub mod parser {
}
}
pub(crate) type JValue = serde_json::Value;
pub(crate) type JValue = air_interpreter_value::JValue;
use air_lambda_parser::LambdaAST;

View File

@ -65,6 +65,7 @@ impl CallRequestParams {
use air_interpreter_interface::TetrapletsRepr;
use air_interpreter_sede::FromSerialized;
// TODO that's different JValue!
let arguments: Vec<JValue> = CallArgumentsRepr
.deserialize(&call_params.arguments)
.map_err(|de_error| CallSeDeErrors::CallParamsArgsDeFailed {

View File

@ -34,6 +34,7 @@ serde_json = "1.0.108"
itertools = "0.10.5"
thiserror = "1.0.50"
tracing = "0.1.40"
air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" }
[dev-dependencies]
criterion = "0.5.1"

View File

@ -191,6 +191,15 @@ impl From<&Number> for serde_json::Value {
}
}
impl From<&Number> for air_interpreter_value::JValue {
fn from(number: &Number) -> Self {
match number {
Number::Int(value) => (*value).into(),
Number::Float(value) => (*value).into(),
}
}
}
fn display_last_error(f: &mut fmt::Formatter, lambda_ast: &Option<LambdaAST>) -> fmt::Result {
use crate::parser::LAST_ERROR;

View File

@ -20,6 +20,7 @@ aquavm-air-parser = { version = "0.11.1", path = "../air-parser" }
air-interpreter-cid = { version = "0.9.0", path = "../interpreter-cid", features = ["rkyv"] }
air-interpreter-signatures = { version = "0.1.7", path = "../interpreter-signatures", features = ["rkyv"] }
air-interpreter-sede = { version = "0.1.0", path = "../interpreter-sede", features = ["msgpack"] }
air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" }
polyplets = { version = "0.6.0", path = "../polyplets", features = ["rkyv"] }
fluence-keypair = { version = "0.10.4", default-features = false }

View File

@ -144,7 +144,7 @@ impl CallServiceFailed {
}
pub fn to_value(&self) -> JValue {
serde_json::to_value(self).expect("default serializer shouldn't fail")
serde_json::to_value(self).expect("default serializer shouldn't fail").into()
}
}

View File

@ -46,7 +46,7 @@ pub use trace::*;
pub use trace_pos::*;
use once_cell::sync::Lazy;
use serde_json::Value as JValue;
use air_interpreter_value::JValue;
use std::str::FromStr;

View File

@ -20,7 +20,6 @@ use serde::Deserialize;
use serde::Serialize;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(transparent)]
@ -31,11 +30,11 @@ pub struct RawValue {
#[serde(skip)]
#[with(::rkyv::with::Skip)]
parsed: RefCell<Option<Rc<JValue>>>,
parsed: RefCell<Option<JValue>>,
}
impl RawValue {
pub fn from_value(value: impl Into<Rc<JValue>>) -> Self {
pub fn from_value(value: impl Into<JValue>) -> Self {
let value = value.into();
let raw = value.to_string().into();
Self {
@ -44,7 +43,7 @@ impl RawValue {
}
}
pub fn get_value(&self) -> Rc<JValue> {
pub fn get_value(&self) -> JValue {
let mut parsed_guard = self.parsed.borrow_mut();
let parsed_value = parsed_guard

View File

@ -23,6 +23,7 @@ marine-call-parameters = { version = "0.10.3", default-features = false }
serde = "1.0.190"
serde_json = "1.0.108"
serde_bytes = "0.11.12"
air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" }
[features]
default = ["marine"]

View File

@ -21,6 +21,7 @@ use air_interpreter_sede::FromSerialized;
use air_interpreter_sede::MsgPackFormat;
use air_interpreter_sede::MsgPackMultiformat;
use air_interpreter_sede::Representation;
use air_interpreter_value::JValue;
use marine_call_parameters::SecurityTetraplet;
#[cfg(feature = "marine")]
@ -43,13 +44,19 @@ pub type CallRequestsFormat = MsgPackMultiformat;
define_simple_representation! {
CallArgumentsRepr,
Vec<serde_json::Value>,
Vec<JValue>,
CallArgumentsFormat,
SerializedCallArguments
}
pub type CallArgumentsDeserializeError = <CallArgumentsRepr as Representation>::DeserializeError;
impl FromSerialized<Vec<serde_json::Value>> for CallArgumentsRepr {
fn deserialize(&self, repr: &[u8]) -> Result<Vec<serde_json::Value>, Self::DeserializeError> {
Self.get_format().from_slice(repr)
}
}
define_simple_representation! {
TetrapletsRepr,
// additional implementation for Vec<Vec<SecurityTetraplet>> is defined below

View File

@ -15,3 +15,5 @@ mod value;
pub type Map<K, V> = indexmap::IndexMap<K, V>;
pub type JsonString = Rc<str>;
pub use value::JValue;

View File

@ -293,3 +293,19 @@ where
}
}
}
impl From<serde_json::Value> for JValue {
fn from(value: serde_json::Value) -> Self {
match value {
serde_json::Value::Null => JValue::Null,
serde_json::Value::Bool(b) => JValue::Bool(b),
serde_json::Value::Number(n) => JValue::Number(n),
serde_json::Value::String(s) => JValue::String(s.into()),
serde_json::Value::Array(a) => JValue::Array(a.into_iter().map(Into::into).collect()),
serde_json::Value::Object(o) => {
let oo = Map::from_iter(o.into_iter().map(|(k, v)| (k.into(), v.into())));
JValue::Object(oo.into())
}
}
}
}

View File

@ -34,6 +34,7 @@ fluence-keypair = "0.10.4"
ed25519-dalek = "2.1.0"
rand_chacha = "0.3.1"
sha2 = "0.10.6"
air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" }
[dev-dependencies]
maplit = "1.0.2"

View File

@ -24,7 +24,7 @@ use std::rc::Rc;
pub fn unit_call_service() -> CallServiceClosure {
Box::new(|_| -> CallServiceResult {
CallServiceResult::ok(json!("result from unit_call_service"))
CallServiceResult::ok(json!("result from unit_call_service").into())
})
}
@ -34,7 +34,7 @@ pub fn echo_call_service() -> CallServiceClosure {
})
}
pub fn set_variable_call_service(json: JValue) -> CallServiceClosure {
pub fn set_variable_call_service(json: serde_json::Value) -> CallServiceClosure {
Box::new(move |_| -> CallServiceResult { CallServiceResult::ok(json.clone()) })
}
@ -47,7 +47,7 @@ pub enum VariableOptionSource {
}
pub fn set_variables_call_service(
variables_mapping: HashMap<String, JValue>,
variables_mapping: HashMap<String, serde_json::Value>,
variable_source: VariableOptionSource,
) -> CallServiceClosure {
use VariableOptionSource::*;
@ -55,7 +55,7 @@ pub fn set_variables_call_service(
Box::new(move |params| -> CallServiceResult {
let var_name = match variable_source {
Argument(id) => match params.arguments.get(id) {
Some(JValue::String(name)) => name.to_string(),
Some(serde_json::Value::String(name)) => name.to_string(),
_ => "default".to_string(),
},
FunctionName => params.function_name,
@ -89,7 +89,7 @@ pub fn fallible_call_service(fallible_service_id: impl Into<String>) -> CallServ
})
}
pub fn fallible_call_service_by_arg(arg: impl Into<JValue>) -> CallServiceClosure {
pub fn fallible_call_service_by_arg(arg: impl Into<serde_json::Value>) -> CallServiceClosure {
let arg = arg.into();
Box::new(move |params| -> CallServiceResult {

View File

@ -45,7 +45,7 @@ use serde::Serialize;
use std::rc::Rc;
pub fn simple_value_aggregate_cid(
result: impl Into<serde_json::Value>,
result: impl Into<JValue>,
cid_state: &mut ExecutionCidState,
) -> CID<ServiceResultCidAggregate> {
let value = result.into();
@ -66,9 +66,9 @@ pub fn simple_value_aggregate_cid(
}
pub fn value_aggregate_cid(
result: impl Into<serde_json::Value>,
result: impl Into<JValue>,
tetraplet: SecurityTetraplet,
args: Vec<serde_json::Value>,
args: Vec<JValue>,
cid_state: &mut ExecutionCidState,
) -> CID<ServiceResultCidAggregate> {
let value = result.into();
@ -76,7 +76,7 @@ pub fn value_aggregate_cid(
let value_cid = cid_state.value_tracker.track_raw_value(vm_value);
let tetraplet_cid = cid_state.tetraplet_tracker.track_value(tetraplet).unwrap();
let arguments = serde_json::Value::Array(args);
let arguments = JValue::Array(args.into());
let argument_hash = value_to_json_cid(&arguments).unwrap().get_inner();
let service_result_agg = ServiceResultCidAggregate {
@ -136,7 +136,7 @@ pub fn ap(generation: impl Into<GenerationIdx>) -> ExecutedState {
#[derive(Debug, Serialize, Deserialize)]
pub struct ValueAggregateAlike {
pub result: Rc<JValue>,
pub result: JValue,
pub tetraplet: Rc<SecurityTetraplet>,
// TODO convert data and remove Provenance
pub provenance: Option<Provenance>,
@ -150,14 +150,14 @@ pub struct CanonResultAlike {
/// This function takes a JSON DSL-like struct for compatibility and test writer
/// convenience.
pub fn canon(canonicalized_element: JValue) -> ExecutedState {
pub fn canon(canonicalized_element: serde_json::Value) -> ExecutedState {
let mut cid_state = ExecutionCidState::new();
canon_tracked(canonicalized_element, &mut cid_state)
}
pub fn canon_tracked(
canonicalized_element: JValue,
canonicalized_element: serde_json::Value,
cid_state: &mut ExecutionCidState,
) -> ExecutedState {
let canon_input = serde_json::from_value::<CanonResultAlike>(canonicalized_element)

View File

@ -51,7 +51,7 @@ pub mod prelude {
pub type CallServiceClosure = Box<dyn Fn(CallRequestParams) -> CallServiceResult + 'static>;
pub type JValue = serde_json::Value;
use air_interpreter_value::JValue;
#[macro_export]
macro_rules! checked_call_vm {

View File

@ -690,7 +690,7 @@ mod tests {
#[test]
fn test_transformed_shared() {
struct Service {
state: RefCell<std::vec::IntoIter<JValue>>,
state: RefCell<std::vec::IntoIter<serde_json::Value>>,
}
impl MarineService for Service {

View File

@ -20,6 +20,7 @@ use air_interpreter_signatures::KeyPair;
use air_test_utils::key_utils::derive_dummy_keypair;
use air_test_utils::prelude::*;
use maplit::hashmap;
use serde_json::Value as JValue;
use std::cell::RefCell;
use std::collections::HashSet;