Skip to content

Commit 871338c

Browse files
MicroProofsKtorZ
andcommitted
feat: Add from asset list to stdlib
Co-authored-by: Matthias Benkort <[email protected]>
1 parent eb39cdd commit 871338c

File tree

2 files changed

+128
-11
lines changed

2 files changed

+128
-11
lines changed

lib/aiken/dict.ak

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,41 @@ fn check_ascending_list(
433433
}
434434
}
435435

436+
pub fn from_ascending_list_with(
437+
xs: List<(key, value)>,
438+
compare: fn(key, key) -> Ordering,
439+
value_predicate: fn(value) -> Bool,
440+
) -> Dict<key, value> {
441+
let Void = check_ascending_list_with(xs, compare, value_predicate)
442+
Dict { inner: xs }
443+
}
444+
445+
fn check_ascending_list_with(
446+
xs: List<(key, value)>,
447+
compare: fn(key, key) -> Ordering,
448+
value_predicate: fn(value) -> Bool,
449+
) {
450+
when xs is {
451+
[] -> Void
452+
[(_, v)] ->
453+
if value_predicate(v) {
454+
Void
455+
} else {
456+
fail @"value doesn't satisfy predicate"
457+
}
458+
[(x0, v0), (x1, _) as e, ..rest] ->
459+
when compare(x0, x1) is {
460+
Less ->
461+
if value_predicate(v0) {
462+
check_ascending_list_with([e, ..rest], compare, value_predicate)
463+
} else {
464+
fail @"value doesn't satisfy predicate"
465+
}
466+
_ -> fail @"keys in associative list aren't in ascending order"
467+
}
468+
}
469+
}
470+
436471
test bench_from_ascending_list() {
437472
let dict =
438473
from_ascending_list(

lib/aiken/transaction/value.ak

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use aiken/bytearray
2-
use aiken/dict.{Dict}
2+
use aiken/dict.{Dict, from_ascending_list_with}
33
use aiken/hash.{Blake2b_224, Hash}
44
use aiken/list
55
use aiken/option
@@ -431,6 +431,86 @@ test reduce_3() {
431431
result == 1
432432
}
433433

434+
pub fn from_asset_list(xs: List<(PolicyId, List<(AssetName, Int)>)>) -> Value {
435+
xs
436+
|> list.foldr(
437+
dict.new(),
438+
fn(inner, acc) {
439+
expect (p, [_, ..] as x) = inner
440+
x
441+
|> from_ascending_list_with(bytearray.compare, fn(v) { v != 0 })
442+
|> dict.insert_with(
443+
acc,
444+
p,
445+
_,
446+
fn(_, _, _) {
447+
fail @"Duplicate policy in the asset list."
448+
},
449+
bytearray.compare,
450+
)
451+
},
452+
)
453+
|> Value
454+
}
455+
456+
test from_asset_list_1() {
457+
let v = from_asset_list([])
458+
v == zero()
459+
}
460+
461+
test from_asset_list_2() fail {
462+
let v = from_asset_list([(#"33", [])])
463+
v == zero()
464+
}
465+
466+
test from_asset_list_3() fail {
467+
let v = from_asset_list([(#"33", [(#"", 0)])])
468+
v == zero()
469+
}
470+
471+
test from_asset_list_4() {
472+
let v = from_asset_list([(#"33", [(#"", 1)])])
473+
flatten(v) == [(#"33", #"", 1)]
474+
}
475+
476+
test from_asset_list_5() {
477+
let v = from_asset_list([(#"33", [(#"", 1), (#"33", 1)])])
478+
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1)]
479+
}
480+
481+
test from_asset_list_6() fail {
482+
let v =
483+
from_asset_list(
484+
[(#"33", [(#"", 1), (#"33", 1)]), (#"33", [(#"", 1), (#"33", 1)])],
485+
)
486+
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1)]
487+
}
488+
489+
test from_asset_list_7() fail {
490+
let v =
491+
from_asset_list(
492+
[(#"33", [(#"", 1), (#"33", 1)]), (#"34", [(#"", 1), (#"", 1)])],
493+
)
494+
flatten(v) == [(#"33", #"", 1), (#"33", #"33", 1), (#"34", #"", 1)]
495+
}
496+
497+
test from_asset_list_8() {
498+
let v =
499+
from_asset_list(
500+
[
501+
(#"33", [(#"", 1), (#"33", 1)]),
502+
(#"34", [(#"31", 1)]),
503+
(#"35", [(#"", 1)]),
504+
],
505+
)
506+
flatten(v) == [
507+
(#"33", #"", 1),
508+
(#"33", #"33", 1),
509+
(#"34", #"31", 1),
510+
(#"35", #"", 1),
511+
]
512+
}
513+
434514
/// Convert the value into a dictionary of dictionaries.
435515
pub fn to_dict(self: Value) -> Dict<PolicyId, Dict<AssetName, Int>> {
436516
self.inner
@@ -454,11 +534,13 @@ pub fn from_minted_value(self: MintedValue) -> Value {
454534
}
455535

456536
test from_minted_value_1() {
457-
flatten(from_minted_value(from_list([]))) == []
537+
flatten(from_minted_value(from_internal_list([]))) == []
458538
}
459539

460540
test from_minted_value_2() {
461-
flatten(from_minted_value(from_list([("p0", "a0", 1)]))) == [("p0", "a0", 1)]
541+
flatten(from_minted_value(from_internal_list([("p0", "a0", 1)]))) == [
542+
("p0", "a0", 1),
543+
]
462544
}
463545

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

471-
flatten(from_minted_value(from_list(assets))) == result
553+
flatten(from_minted_value(from_internal_list(assets))) == result
472554
}
473555

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

487-
flatten(from_minted_value(from_list(assets))) == result
569+
flatten(from_minted_value(from_internal_list(assets))) == result
488570
}
489571

490572
test from_minted_value_5() {
@@ -507,17 +589,17 @@ test from_minted_value_5() {
507589
("p3", "a7", 1),
508590
]
509591

510-
flatten(from_minted_value(from_list(assets))) == assets
592+
flatten(from_minted_value(from_internal_list(assets))) == assets
511593
}
512594

513595
/// Convert a [`Value`](#Value) into a [`MintedValue`](#MintedValue).
514596
pub fn to_minted_value(self: Value) -> MintedValue {
515597
self.inner
516598
|> dict.insert(
517-
ada_policy_id,
518-
dict.insert(dict.new(), ada_asset_name, 0, bytearray.compare),
519-
bytearray.compare,
520-
)
599+
ada_policy_id,
600+
dict.insert(dict.new(), ada_asset_name, 0, bytearray.compare),
601+
bytearray.compare,
602+
)
521603
|> MintedValue
522604
}
523605

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

0 commit comments

Comments
 (0)