Repository: ergoplatform/sigma-rust (language: rust)

Issue:
Expose ErgoTree pretty print in Wasm API



Discussion / hints:

Fix patch:
diff --git a/bindings/ergo-lib-wasm/src/ergo_tree.rs b/bindings/ergo-lib-wasm/src/ergo_tree.rs
index 1f5d44d7f..476831026 100644
--- a/bindings/ergo-lib-wasm/src/ergo_tree.rs
+++ b/bindings/ergo-lib-wasm/src/ergo_tree.rs
@@ -71,4 +71,9 @@ impl ErgoTree {
     pub fn template_bytes(&self) -> Result<Vec<u8>, JsValue> {
         self.0.template_bytes().map_err(to_js)
     }
+
+    /// Returns pretty printed tree
+    pub fn pretty_print(&self) -> Result<String, JsValue> {
+        Ok(self.0.pretty_print().map_err(to_js)?.1)
+    }
 }
diff --git a/bindings/ergo-lib-wasm/src/error_conversion.rs b/bindings/ergo-lib-wasm/src/error_conversion.rs
index b38ae2e93..922a2d89d 100644
--- a/bindings/ergo-lib-wasm/src/error_conversion.rs
+++ b/bindings/ergo-lib-wasm/src/error_conversion.rs
@@ -98,6 +98,7 @@ from_error_to_wrap!(ConvError);
 from_error_to_wrap!(TransactionContextError);
 from_error_to_wrap!(TxVerifyError);
 from_error_to_wrap!(RegisterValueError);
+from_error_to_wrap!(String);
 
 macro_rules! from_error_to_wrap_via_debug {
     ($t:ident) => {
diff --git a/ergotree-interpreter/src/eval.rs b/ergotree-interpreter/src/eval.rs
index bb3853da2..6cf3503e9 100644
--- a/ergotree-interpreter/src/eval.rs
+++ b/ergotree-interpreter/src/eval.rs
@@ -1,7 +1,5 @@
 //! Interpreter
 use ergotree_ir::mir::constant::TryExtractInto;
-use ergotree_ir::pretty_printer::PosTrackingWriter;
-use ergotree_ir::pretty_printer::Print;
 use ergotree_ir::sigma_protocol::sigma_boolean::SigmaProp;
 use std::fmt::Display;
 use std::rc::Rc;
@@ -165,7 +163,9 @@ pub fn reduce_to_crypto(
     let res = inner(expr, env, ctx);
     if let Ok(reduction) = res {
         if reduction.sigma_prop == SigmaBoolean::TrivialProp(false) {
-            let (_, printed_expr_str) = pretty_print(expr)?;
+            let (_, printed_expr_str) = expr
+                .pretty_print()
+                .map_err(|e| EvalError::Misc(e.to_string()))?;
             let new_reduction = ReductionResult {
                 sigma_prop: SigmaBoolean::TrivialProp(false),
                 cost: reduction.cost,
@@ -179,20 +179,13 @@ pub fn reduce_to_crypto(
             return Ok(reduction);
         }
     }
-    let (spanned_expr, printed_expr_str) = pretty_print(expr)?;
+    let (spanned_expr, printed_expr_str) = expr
+        .pretty_print()
+        .map_err(|e| EvalError::Misc(e.to_string()))?;
     inner(&spanned_expr, env, ctx_clone)
         .map_err(|e| e.wrap_spanned_with_src(printed_expr_str.to_string()))
 }
 
-fn pretty_print(expr: &Expr) -> Result<(Expr, String), EvalError> {
-    let mut printer = PosTrackingWriter::new();
-    let spanned_expr = expr
-        .print(&mut printer)
-        .map_err(|e| EvalError::Misc(format!("printer error: {}", e)))?;
-    let printed_expr_str = printer.get_buf();
-    Ok((spanned_expr, printed_expr_str.to_owned()))
-}
-
 /// Expects SigmaProp constant value and returns it's value. Otherwise, returns an error.
 pub fn extract_sigma_boolean(expr: &Expr) -> Result<SigmaBoolean, EvalError> {
     match expr {
diff --git a/ergotree-ir/src/ergo_tree.rs b/ergotree-ir/src/ergo_tree.rs
index ec0f7bdf7..6859bc6f9 100644
--- a/ergotree-ir/src/ergo_tree.rs
+++ b/ergotree-ir/src/ergo_tree.rs
@@ -233,6 +233,12 @@ impl ErgoTree {
         tree
     }
 
+    /// Returns pretty printed tree
+    pub fn pretty_print(&self) -> Result<(Expr, String), String> {
+        let tree = self.parsed_tree().map_err(|e| e.to_string())?;
+        tree.root.pretty_print().map_err(|e| e.to_string())
+    }
+
     /// Returns Base16-encoded serialized bytes
     pub fn to_base16_bytes(&self) -> Result<String, SigmaSerializationError> {
         let bytes = self.sigma_serialize_bytes()?;
diff --git a/ergotree-ir/src/pretty_printer/print.rs b/ergotree-ir/src/pretty_printer/print.rs
index 870ff6c13..ca1f996bd 100644
--- a/ergotree-ir/src/pretty_printer/print.rs
+++ b/ergotree-ir/src/pretty_printer/print.rs
@@ -69,6 +69,7 @@ use crate::source_span::SourceSpan;
 use crate::source_span::Spanned;
 use crate::types::stype::SType;
 
+use super::PosTrackingWriter;
 use super::Printer;
 
 /// Print error
@@ -79,6 +80,16 @@ pub enum PrintError {
     FmtError(#[from] std::fmt::Error),
 }
 
+impl Expr {
+    /// Returns pretty printed tree
+    pub fn pretty_print(&self) -> Result<(Expr, String), PrintError> {
+        let mut printer = PosTrackingWriter::new();
+        let spanned_expr = self.print(&mut printer)?;
+        let printed_expr_str = printer.get_buf();
+        Ok((spanned_expr, printed_expr_str.to_owned()))
+    }
+}
+
 /// Print trait for Expr that sets the source span for the resulting Expr
 pub trait Print {
     /// Print the expression and return the resulting expression with source span


Test patch: