Skip to content

Commit

Permalink
feat: Add from asset list to stdlib
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Benkort <[email protected]>
  • Loading branch information
MicroProofs and KtorZ committed Mar 22, 2024
1 parent eb39cdd commit 871338c
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 11 deletions.
35 changes: 35 additions & 0 deletions lib/aiken/dict.ak
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,41 @@ fn check_ascending_list(
}
}

pub fn from_ascending_list_with(
xs: List<(key, value)>,
compare: fn(key, key) -> Ordering,
value_predicate: fn(value) -> Bool,
) -> Dict<key, value> {
let Void = check_ascending_list_with(xs, compare, value_predicate)
Dict { inner: xs }
}

fn check_ascending_list_with(
xs: List<(key, value)>,
compare: fn(key, key) -> Ordering,
value_predicate: fn(value) -> Bool,
) {
when xs is {
[] -> Void
[(_, v)] ->
if value_predicate(v) {
Void
} else {
fail @"value doesn't satisfy predicate"
}
[(x0, v0), (x1, _) as e, ..rest] ->
when compare(x0, x1) is {
Less ->
if value_predicate(v0) {
check_ascending_list_with([e, ..rest], compare, value_predicate)
} else {
fail @"value doesn't satisfy predicate"
}
_ -> fail @"keys in associative list aren't in ascending order"
}
}
}

test bench_from_ascending_list() {
let dict =
from_ascending_list(
Expand Down
104 changes: 93 additions & 11 deletions lib/aiken/transaction/value.ak
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use aiken/bytearray
use aiken/dict.{Dict}
use aiken/dict.{Dict, from_ascending_list_with}
use aiken/hash.{Blake2b_224, Hash}
use aiken/list
use aiken/option
Expand Down Expand Up @@ -431,6 +431,86 @@ test reduce_3() {
result == 1
}

pub fn from_asset_list(xs: List<(PolicyId, List<(AssetName, Int)>)>) -> Value {
xs
|> list.foldr(
dict.new(),
fn(inner, acc) {
expect (p, [_, ..] as x) = inner
x
|> from_ascending_list_with(bytearray.compare, fn(v) { v != 0 })
|> dict.insert_with(
acc,
p,
_,
fn(_, _, _) {
fail @"Duplicate policy in the asset list."
},
bytearray.compare,
)
},
)
|> Value
}

test from_asset_list_1() {
let v = from_asset_list([])
v == zero()
}

test from_asset_list_2() fail {
let v = from_asset_list([(#"33", [])])
v == zero()
}

test from_asset_list_3() fail {
let v = from_asset_list([(#"33", [(#"", 0)])])
v == zero()
}

test from_asset_list_4() {
let v = from_asset_list([(#"33", [(#"", 1)])])
flatten(v) == [(#"33", #"", 1)]
}

test from_asset_list_5() {
let v = from_asset_list([(#"33", [(#"", 1), (#"33", 1)])])
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1)]
}

test from_asset_list_6() fail {
let v =
from_asset_list(
[(#"33", [(#"", 1), (#"33", 1)]), (#"33", [(#"", 1), (#"33", 1)])],
)
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1)]
}

test from_asset_list_7() fail {
let v =
from_asset_list(
[(#"33", [(#"", 1), (#"33", 1)]), (#"34", [(#"", 1), (#"", 1)])],
)
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1), (#"34", #"", 1)]
}

test from_asset_list_8() {
let v =
from_asset_list(
[
(#"33", [(#"", 1), (#"33", 1)]),
(#"34", [(#"31", 1)]),
(#"35", [(#"", 1)]),
],
)
flatten(v) == [
(#"33", #"", 1),
(#"33", #"33", 1),
(#"34", #"31", 1),
(#"35", #"", 1),
]
}

/// Convert the value into a dictionary of dictionaries.
pub fn to_dict(self: Value) -> Dict<PolicyId, Dict<AssetName, Int>> {
self.inner
Expand All @@ -454,11 +534,13 @@ pub fn from_minted_value(self: MintedValue) -> Value {
}

test from_minted_value_1() {
flatten(from_minted_value(from_list([]))) == []
flatten(from_minted_value(from_internal_list([]))) == []
}

test from_minted_value_2() {
flatten(from_minted_value(from_list([("p0", "a0", 1)]))) == [("p0", "a0", 1)]
flatten(from_minted_value(from_internal_list([("p0", "a0", 1)]))) == [
("p0", "a0", 1),
]
}

test from_minted_value_3() {
Expand All @@ -468,7 +550,7 @@ test from_minted_value_3() {
let result =
[("p0", "a0", 2), ("p1", "a0", 1), ("p1", "a1", 1)]

flatten(from_minted_value(from_list(assets))) == result
flatten(from_minted_value(from_internal_list(assets))) == result
}

test from_minted_value_4() {
Expand All @@ -484,7 +566,7 @@ test from_minted_value_4() {
let result =
[("p0", "a0", 2), ("p1", "a0", 1), ("p1", "a1", 1)]

flatten(from_minted_value(from_list(assets))) == result
flatten(from_minted_value(from_internal_list(assets))) == result
}

test from_minted_value_5() {
Expand All @@ -507,17 +589,17 @@ test from_minted_value_5() {
("p3", "a7", 1),
]

flatten(from_minted_value(from_list(assets))) == assets
flatten(from_minted_value(from_internal_list(assets))) == assets
}

/// Convert a [`Value`](#Value) into a [`MintedValue`](#MintedValue).
pub fn to_minted_value(self: Value) -> MintedValue {
self.inner
|> dict.insert(
ada_policy_id,
dict.insert(dict.new(), ada_asset_name, 0, bytearray.compare),
bytearray.compare,
)
ada_policy_id,
dict.insert(dict.new(), ada_asset_name, 0, bytearray.compare),
bytearray.compare,
)
|> MintedValue
}

Expand All @@ -539,7 +621,7 @@ test to_minted_value_2() {
///
/// NOTE: Not exposed because we do not want people to construct `MintedValue`. Only
/// get them from the script context.
fn from_list(xs: List<(PolicyId, AssetName, Int)>) -> MintedValue {
fn from_internal_list(xs: List<(PolicyId, AssetName, Int)>) -> MintedValue {
list.foldr(
xs,
MintedValue(dict.new()),
Expand Down

0 comments on commit 871338c

Please sign in to comment.