Skip to content

Commit e3c3dba

Browse files
btc: Address field accessors
1 parent bf0d59a commit e3c3dba

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

src/parser/grammar.lalrpop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ ArrayCurly: Expr = "{" <e1:Expr> "," <e2:Expr> "}" =>
170170

171171
// Array/Field child access
172172
ChildAccess = { ArrayAccess, FieldAccess }; // left-associative recursion
173-
ChildAccessLHS = { Ident, SimpleCall, BlockExpr, Bytes, ChildAccess }; // would be nice to have: Array, Paren<Expr>
173+
ChildAccessLHS = { ChildAccess, Ident, SimpleCall, BlockExpr, Address, PubKey, SecKey }; // would be nice to have: Array, Paren<Expr>
174174

175175
// Array element access - `$arr.3`, `$arr.$n`, `$arr.($n+1)`, `$arr.{$n+1}`
176176
ArrayAccess_: Expr = <array:ChildAccessLHS> "." <index:ArrayAccessRHS> =>

src/runtime/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -246,18 +246,6 @@ impl Evaluate for ast::FieldAccess {
246246
pub trait FieldAccess {
247247
fn get_field(self, field: &Value) -> Option<Value>;
248248
}
249-
impl FieldAccess for Value {
250-
fn get_field(self, field: &Value) -> Option<Value> {
251-
match self {
252-
Value::Array(x) => x.get_field(field),
253-
Value::Psbt(x) => x.get_field(field),
254-
Value::Transaction(x) => x.get_field(field),
255-
Value::Descriptor(x) => x.get_field(field),
256-
Value::TapInfo(x) => x.get_field(field),
257-
_ => None,
258-
}
259-
}
260-
}
261249

262250
impl Evaluate for ast::FnExpr {
263251
fn eval(&self, scope: &ScopeRef) -> Result<Value> {

src/runtime/value.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bitcoin::{
1111
use descriptor::{DescriptorPublicKey, DescriptorSecretKey};
1212

1313
use crate::parser::Expr;
14-
use crate::runtime::{Array, Error, Evaluate, Function, Result, Scope};
14+
use crate::runtime::{Array, Error, Evaluate, FieldAccess, Function, Result, Scope};
1515
use crate::util::{fmt_quoted_str, PrettyDisplay, EC};
1616
use crate::{error, stdlib, DescriptorDpk as Descriptor, PolicyDpk as Policy};
1717
use stdlib::btc::WshScript;
@@ -112,7 +112,6 @@ impl_simple_into_variant!(Function, Function, into_fn, NotFn);
112112
impl_simple_into_variant!(String, String, into_string, NotString);
113113
impl_simple_into_variant!(WshScript, WshScript, into_wsh_script, NotWshScript);
114114

115-
116115
// From Value to f64 primitive, with auto-coercion for integers
117116
impl TryFrom<Value> for f64 {
118117
type Error = Error;
@@ -513,6 +512,20 @@ impl ExprRepr for Value {
513512
}
514513
}
515514

515+
impl FieldAccess for Value {
516+
fn get_field(self, field: &Value) -> Option<Value> {
517+
match self {
518+
Value::Array(x) => x.get_field(field),
519+
Value::Psbt(x) => x.get_field(field),
520+
Value::Transaction(x) => x.get_field(field),
521+
Value::Descriptor(x) => x.get_field(field),
522+
Value::TapInfo(x) => x.get_field(field),
523+
Value::Address(x) => x.get_field(field),
524+
_ => None,
525+
}
526+
}
527+
}
528+
516529
// Symbol
517530
//
518531
// A Value type guaranteed to be unique. Symbols don't have any special meaning on the Rust side, but are used in

src/stdlib/btc.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ impl_simple_to_value!(Sequence, seq, seq.to_consensus_u32());
475475
impl_simple_to_value!(AbsLockTime, time, time.to_consensus_u32());
476476
impl_simple_to_value!(OutPoint, outpoint, (outpoint.txid, outpoint.vout));
477477
impl_simple_to_value!(Witness, wit, wit.to_vec());
478+
impl_simple_to_value!(bitcoin::WitnessVersion, ver, ver.to_num() as i64);
479+
impl_simple_to_value!(bitcoin::AddressType, t, t.to_string());
480+
impl_simple_to_value!(bitcoin::WitnessProgram, w, (w.version(), w.program()));
481+
impl_simple_to_value!(&bitcoin::script::PushBytes, p, p.as_bytes().to_vec());
478482
impl_simple_to_value!(SignedAmount, amt, amt.to_sat());
479483
// Panics for out-of-range `Amount`s (i64 can represent up to ~92 billion BTC, ~4400x more than can exists),
480484
// which should be impossible to construct within Minsc (but can be passed from Rust code).
@@ -513,7 +517,8 @@ impl_simple_to_value!(
513517
i64::try_from(w.to_wu()).expect("out of range weight")
514518
);
515519

516-
// Transaction fields accessors
520+
// Field accessors
521+
517522
impl FieldAccess for Transaction {
518523
fn get_field(self, field: &Value) -> Option<Value> {
519524
Some(match field.as_str()? {
@@ -533,6 +538,20 @@ impl FieldAccess for Transaction {
533538
}
534539
}
535540

541+
impl FieldAccess for Address {
542+
fn get_field(self, field: &Value) -> Option<Value> {
543+
Some(match field.as_str()? {
544+
"script_pubkey" => self.script_pubkey().into(),
545+
"address_type" => self.address_type()?.into(),
546+
"witness_program" => self.witness_program()?.into(),
547+
"qr_uri" => self.to_qr_uri().into(),
548+
_ => {
549+
return None;
550+
}
551+
})
552+
}
553+
}
554+
536555
// Display
537556

538557
impl PrettyDisplay for ScriptBuf {

0 commit comments

Comments
 (0)