-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unified tx syntax - blackbox prototype
- Loading branch information
1 parent
669ff3a
commit ae054e1
Showing
18 changed files
with
623 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use crate::{ | ||
api::ManagedTypeApi, | ||
types::{ManagedAddress, ManagedBuffer}, | ||
}; | ||
|
||
pub trait AnnotatedValue<Api, T> | ||
where | ||
Api: ManagedTypeApi, | ||
{ | ||
fn annotation(&self) -> ManagedBuffer<Api>; | ||
|
||
fn into_value(self) -> T; | ||
|
||
fn with_value_ref<F: FnOnce(&T)>(&self, f: F); | ||
} | ||
|
||
impl<Api> AnnotatedValue<Api, ManagedAddress<Api>> for ManagedAddress<Api> | ||
where | ||
Api: ManagedTypeApi, | ||
{ | ||
fn annotation(&self) -> ManagedBuffer<Api> { | ||
self.hex_expr() | ||
} | ||
|
||
fn into_value(self) -> ManagedAddress<Api> { | ||
self | ||
} | ||
|
||
fn with_value_ref<F: FnOnce(&ManagedAddress<Api>)>(&self, f: F) { | ||
f(self) | ||
} | ||
} | ||
|
||
impl<Api> AnnotatedValue<Api, ManagedAddress<Api>> for &ManagedAddress<Api> | ||
where | ||
Api: ManagedTypeApi, | ||
{ | ||
fn annotation(&self) -> crate::types::ManagedBuffer<Api> { | ||
self.hex_expr() | ||
} | ||
|
||
fn into_value(self) -> ManagedAddress<Api> { | ||
self.clone() | ||
} | ||
|
||
fn with_value_ref<F: FnOnce(&ManagedAddress<Api>)>(&self, f: F) { | ||
f(self) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
use core::ptr; | ||
|
||
use crate::{ | ||
api::CallTypeApi, | ||
types::{ManagedAddress, ManagedBuffer}, | ||
}; | ||
|
||
use super::{AnnotatedValue, TxFrom, TxFromSpecified}; | ||
|
||
const ADDRESS_PREFIX: &str = "address:"; | ||
|
||
#[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
pub struct AddressExpr(pub &'static str); | ||
|
||
impl<Api> AnnotatedValue<Api, ManagedAddress<Api>> for AddressExpr | ||
where | ||
Api: CallTypeApi, | ||
{ | ||
fn annotation(&self) -> ManagedBuffer<Api> { | ||
let mut result = ManagedBuffer::new_from_bytes(ADDRESS_PREFIX.as_bytes()); | ||
result.append_bytes(self.0.as_bytes()); | ||
result | ||
} | ||
|
||
fn into_value(self) -> ManagedAddress<Api> { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
expr.into() | ||
} | ||
|
||
fn with_value_ref<F: FnOnce(&ManagedAddress<Api>)>(&self, f: F) { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
let ma = expr.into(); | ||
f(&ma); | ||
} | ||
} | ||
impl<Api> TxFrom<Api> for AddressExpr | ||
where | ||
Api: CallTypeApi, | ||
{ | ||
fn resolve_address(&self) -> ManagedAddress<Api> { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
expr.into() | ||
} | ||
} | ||
impl<Api> TxFromSpecified<Api> for AddressExpr where Api: CallTypeApi {} | ||
|
||
impl AddressExpr { | ||
pub const fn eval_to_array(&self) -> [u8; 32] { | ||
let result = [b'_'; 32]; | ||
let expr_bytes = self.0.as_bytes(); | ||
let mut len = expr_bytes.len(); | ||
if len > 32 { | ||
len = 32; | ||
} | ||
unsafe { | ||
ptr::copy_nonoverlapping(expr_bytes.as_ptr(), result.as_ptr() as *mut u8, len); | ||
} | ||
result | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
pub mod tests { | ||
use super::*; | ||
|
||
fn assert_eq_eval(expr: &'static str, expected: &[u8; 32]) { | ||
assert_eq!(&AddressExpr(expr).eval_to_array(), expected); | ||
} | ||
|
||
#[test] | ||
fn test_address_value() { | ||
assert_eq_eval("", b"________________________________"); | ||
assert_eq_eval("a", b"a_______________________________"); | ||
assert_eq_eval("a\x05", b"a\x05______________________________"); | ||
assert_eq_eval("an_address", b"an_address______________________"); | ||
assert_eq_eval( | ||
"12345678901234567890123456789012", | ||
b"12345678901234567890123456789012", | ||
); | ||
assert_eq_eval( | ||
"123456789012345678901234567890123", | ||
b"12345678901234567890123456789012", | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use core::ptr; | ||
|
||
use crate::{ | ||
api::CallTypeApi, | ||
types::{ManagedAddress, ManagedBuffer}, | ||
}; | ||
|
||
use super::{AnnotatedValue, TxFrom, TxFromSpecified, TxTo, TxToSpecified}; | ||
|
||
const SC_PREFIX: &str = "sc:"; | ||
|
||
#[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
pub struct ScExpr<'a>(pub &'a str); | ||
|
||
impl<'a, Api> AnnotatedValue<Api, ManagedAddress<Api>> for ScExpr<'a> | ||
where | ||
Api: CallTypeApi, | ||
{ | ||
fn annotation(&self) -> ManagedBuffer<Api> { | ||
let mut result = ManagedBuffer::new_from_bytes(SC_PREFIX.as_bytes()); | ||
result.append_bytes(self.0.as_bytes()); | ||
result | ||
} | ||
|
||
fn into_value(self) -> ManagedAddress<Api> { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
expr.into() | ||
} | ||
|
||
fn with_value_ref<F: FnOnce(&ManagedAddress<Api>)>(&self, f: F) { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
let ma = expr.into(); | ||
f(&ma); | ||
} | ||
} | ||
impl<'a, Api> TxFrom<Api> for ScExpr<'a> | ||
where | ||
Api: CallTypeApi, | ||
{ | ||
fn resolve_address(&self) -> ManagedAddress<Api> { | ||
let expr: [u8; 32] = self.eval_to_array(); | ||
expr.into() | ||
} | ||
} | ||
impl<'a, Api> TxFromSpecified<Api> for ScExpr<'a> where Api: CallTypeApi {} | ||
impl<'a, Api> TxTo<Api> for ScExpr<'a> where Api: CallTypeApi {} | ||
impl<'a, Api> TxToSpecified<Api> for ScExpr<'a> where Api: CallTypeApi {} | ||
|
||
impl<'a> ScExpr<'a> { | ||
pub const fn eval_to_array(&self) -> [u8; 32] { | ||
let result = *b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00______________________"; | ||
let expr_bytes = self.0.as_bytes(); | ||
let mut len = expr_bytes.len(); | ||
if len > 22 { | ||
len = 22; | ||
} | ||
unsafe { | ||
ptr::copy_nonoverlapping( | ||
expr_bytes.as_ptr(), | ||
result.as_ptr().offset(10) as *mut u8, | ||
len, | ||
); | ||
} | ||
result | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
pub mod tests { | ||
use super::*; | ||
|
||
fn assert_eq_eval(expr: &'static str, expected: &[u8; 32]) { | ||
assert_eq!(&ScExpr(expr).eval_to_array(), expected); | ||
} | ||
|
||
#[test] | ||
fn test_address_value() { | ||
assert_eq_eval( | ||
"", | ||
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00______________________", | ||
); | ||
assert_eq_eval( | ||
"a", | ||
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a_____________________", | ||
); | ||
assert_eq_eval( | ||
"12345678901234567890120s", | ||
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001234567890123456789012", | ||
); | ||
} | ||
|
||
// #[test] | ||
// fn test_sc_address() { | ||
// let context = InterpreterContext::default(); | ||
// assert_eq!( | ||
// b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a_____________________".to_vec(), | ||
// interpret_string("sc:a", &context) | ||
// ); | ||
// assert_eq!( | ||
// b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001234567890123456789012".to_vec(), | ||
// interpret_string("sc:12345678901234567890120s", &context) | ||
// ); | ||
// // trims excess | ||
// assert_eq!( | ||
// b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001234567890123456789012".to_vec(), | ||
// interpret_string("sc:12345678901234567890120sx", &context) | ||
// ); | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.