Skip to content
Snippets Groups Projects

Json output

Open poka requested to merge json-output into master
19 files
+ 1538
501
Compare changes
  • Side-by-side
  • Inline
Files
19
+ 230
14
@@ -4,6 +4,7 @@ use crate::entities::vault_account::AccountTreeNode;
@@ -4,6 +4,7 @@ use crate::entities::vault_account::AccountTreeNode;
use crate::keys::CryptoScheme;
use crate::keys::CryptoScheme;
use crate::utils::GcliError;
use crate::utils::GcliError;
use comfy_table::{Cell, Table};
use comfy_table::{Cell, Table};
 
use serde::Serialize;
use std::cell::RefCell;
use std::cell::RefCell;
use std::rc::Rc;
use std::rc::Rc;
use std::str;
use std::str;
@@ -25,34 +26,49 @@ pub fn compute_vault_key_files_table(vault_key_addresses: &[String]) -> Result<T
@@ -25,34 +26,49 @@ pub fn compute_vault_key_files_table(vault_key_addresses: &[String]) -> Result<T
pub fn compute_vault_accounts_table(
pub fn compute_vault_accounts_table(
account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
 
) -> Result<Table, GcliError> {
 
// Appel to the new function with show_g1v1 = true to maintain compatibility
 
compute_vault_accounts_table_with_g1v1(account_tree_nodes, true)
 
}
 
 
pub fn compute_vault_accounts_table_with_g1v1(
 
account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
 
show_g1v1: bool,
) -> Result<Table, GcliError> {
) -> Result<Table, GcliError> {
let mut table = Table::new();
let mut table = Table::new();
table.load_preset(comfy_table::presets::UTF8_BORDERS_ONLY);
table.load_preset(comfy_table::presets::UTF8_BORDERS_ONLY);
 
 
// Prepare header based on options
table.set_header(vec![
table.set_header(vec![
"SS58 Address/G1v1 public key",
if show_g1v1 {
 
"SS58 Address/G1v1 public key"
 
} else {
 
"SS58 Address"
 
},
"Crypto",
"Crypto",
"Path",
"Path",
"Name",
"Name",
]);
]);
for account_tree_node in account_tree_nodes {
for account_tree_node in account_tree_nodes {
let _ = add_account_tree_node_to_table(&mut table, account_tree_node);
let _ = add_account_tree_node_to_table_with_g1v1(&mut table, account_tree_node, show_g1v1);
}
}
Ok(table)
Ok(table)
}
}
fn add_account_tree_node_to_table(
fn add_account_tree_node_to_table_with_g1v1(
table: &mut Table,
table: &mut Table,
account_tree_node: &Rc<RefCell<AccountTreeNode>>,
account_tree_node: &Rc<RefCell<AccountTreeNode>>,
 
show_g1v1: bool,
) -> Result<(), GcliError> {
) -> Result<(), GcliError> {
let rows = compute_vault_accounts_row(account_tree_node)?;
let rows = compute_vault_accounts_row_with_g1v1(account_tree_node, show_g1v1)?;
rows.iter().for_each(|row| {
rows.iter().for_each(|row| {
table.add_row(row.clone());
table.add_row(row.clone());
});
});
for child in &account_tree_node.borrow().children {
for child in &account_tree_node.borrow().children {
let _ = add_account_tree_node_to_table(table, child);
let _ = add_account_tree_node_to_table_with_g1v1(table, child, show_g1v1);
}
}
Ok(())
Ok(())
@@ -60,9 +76,10 @@ fn add_account_tree_node_to_table(
@@ -60,9 +76,10 @@ fn add_account_tree_node_to_table(
/// Computes one or more row of the table for selected account_tree_node
/// Computes one or more row of the table for selected account_tree_node
///
///
/// For ed25519 keys, will display over 2 rows to also show the base 58 G1v1 public key
/// For ed25519 keys, will display over 2 rows to also show the base 58 G1v1 public key if show_g1v1 is true
pub fn compute_vault_accounts_row(
pub fn compute_vault_accounts_row_with_g1v1(
account_tree_node: &Rc<RefCell<AccountTreeNode>>,
account_tree_node: &Rc<RefCell<AccountTreeNode>>,
 
show_g1v1: bool,
) -> Result<Vec<Vec<Cell>>, GcliError> {
) -> Result<Vec<Vec<Cell>>, GcliError> {
let empty_string = "".to_string();
let empty_string = "".to_string();
@@ -93,25 +110,33 @@ pub fn compute_vault_accounts_row(
@@ -93,25 +110,33 @@ pub fn compute_vault_accounts_row(
(path, empty_string.clone())
(path, empty_string.clone())
} else {
} else {
let crypto_scheme = CryptoScheme::from(account_tree_node.account.crypto_scheme.unwrap());
let crypto_scheme = CryptoScheme::from(account_tree_node.account.crypto_scheme.unwrap());
 
let crypto_scheme_str: &str = crypto_scheme.into();
// Adding 2nd row for G1v1 public key
// Add a second line for the G1v1 public key only if show_g1v1 is true and it's an Ed25519 key
if CryptoScheme::Ed25519 == crypto_scheme {
let is_ed25519 = crypto_scheme == CryptoScheme::Ed25519;
rows.push(vec![Cell::new(format!(
if show_g1v1 && is_ed25519 {
 
let mut g1v1_row = vec![Cell::new(format!(
"└ G1v1: {}",
"└ G1v1: {}",
cesium::compute_g1v1_public_key_from_ed25519_account_id(
cesium::compute_g1v1_public_key_from_ed25519_account_id(
&account_tree_node.account.address.0
&account_tree_node.account.address.0
)
)
))]);
))];
 
 
// Add empty cells to align with the main line
 
g1v1_row.push(Cell::new(""));
 
g1v1_row.push(Cell::new(""));
 
g1v1_row.push(Cell::new(""));
 
 
rows.push(g1v1_row);
}
}
let crypto_scheme_str: &str = crypto_scheme.into();
(
(
format!("<{}>", account_tree_node.account.account_type()),
format!("<{}>", account_tree_node.account.account_type()),
crypto_scheme_str.to_string(),
crypto_scheme_str.to_string(),
)
)
};
};
// Adding 1st row
// Add the first line
rows.insert(
rows.insert(
0,
0,
vec![
vec![
@@ -125,15 +150,101 @@ pub fn compute_vault_accounts_row(
@@ -125,15 +150,101 @@ pub fn compute_vault_accounts_row(
Ok(rows)
Ok(rows)
}
}
 
/// Serializable structure for JSON output
 
#[derive(Serialize)]
 
pub struct VaultAccountView {
 
address: String,
 
crypto_scheme: Option<String>,
 
path: String,
 
name: String,
 
g1v1_public_key: Option<String>,
 
children: Vec<VaultAccountView>,
 
}
 
 
/// Compute a serializable structure for JSON output
 
pub fn compute_vault_accounts_json(
 
account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
 
show_g1v1: bool,
 
) -> Vec<VaultAccountView> {
 
let mut result = Vec::new();
 
 
for account_tree_node in account_tree_nodes {
 
result.push(compute_vault_account_json(account_tree_node, show_g1v1));
 
}
 
 
result
 
}
 
 
/// Compute a serializable structure for a single account tree node
 
fn compute_vault_account_json(
 
account_tree_node: &Rc<RefCell<AccountTreeNode>>,
 
show_g1v1: bool,
 
) -> VaultAccountView {
 
let empty_string = "".to_string();
 
let borrowed_node = account_tree_node.borrow();
 
 
let name = if let Some(name) = borrowed_node.account.name.clone() {
 
name
 
} else if let Some(computed_name) =
 
vault_account::compute_name_account_tree_node(account_tree_node)
 
{
 
format!("<{}>", computed_name)
 
} else {
 
empty_string.clone()
 
};
 
 
let (path, crypto_scheme, g1v1_public_key) =
 
if let Some(path) = borrowed_node.account.path.clone() {
 
(path, None, None)
 
} else {
 
let crypto_scheme = borrowed_node.account.crypto_scheme.map(|cs| {
 
let scheme = CryptoScheme::from(cs);
 
let scheme_str: &str = scheme.into();
 
scheme_str.to_string()
 
});
 
 
let g1v1_public_key = if show_g1v1 && crypto_scheme.as_deref() == Some("ed25519") {
 
Some(cesium::compute_g1v1_public_key_from_ed25519_account_id(
 
&borrowed_node.account.address.0,
 
))
 
} else {
 
None
 
};
 
 
(
 
format!("<{}>", borrowed_node.account.account_type()),
 
crypto_scheme,
 
g1v1_public_key,
 
)
 
};
 
 
let mut children = Vec::new();
 
for child in &borrowed_node.children {
 
children.push(compute_vault_account_json(child, show_g1v1));
 
}
 
 
VaultAccountView {
 
address: borrowed_node.account.address.to_string(),
 
crypto_scheme,
 
path,
 
name,
 
g1v1_public_key,
 
children,
 
}
 
}
 
#[cfg(test)]
#[cfg(test)]
mod tests {
mod tests {
mod vault_accounts_table_tests {
mod vault_accounts_table_tests {
use crate::commands::vault::display::compute_vault_accounts_table;
use crate::commands::vault::display::{
 
compute_vault_accounts_table, compute_vault_accounts_table_with_g1v1,
 
};
use crate::entities::vault_account::tests::account_tree_node_tests::{
use crate::entities::vault_account::tests::account_tree_node_tests::{
mother_account_tree_node, mother_g1v1_account_tree_node,
mother_account_tree_node, mother_g1v1_account_tree_node,
};
};
use indoc::indoc;
use indoc::indoc;
 
// Tests for compute_vault_accounts_table (old function)
#[test]
#[test]
fn test_compute_vault_accounts_table_empty() {
fn test_compute_vault_accounts_table_empty() {
let table = compute_vault_accounts_table(&[]).unwrap();
let table = compute_vault_accounts_table(&[]).unwrap();
@@ -191,5 +302,110 @@ mod tests {
@@ -191,5 +302,110 @@ mod tests {
assert_eq!(table.to_string(), expected_table);
assert_eq!(table.to_string(), expected_table);
}
}
 
 
// Tests for compute_vault_accounts_table_with_g1v1
 
#[test]
 
fn test_compute_vault_accounts_table_with_g1v1_empty() {
 
// Test with show_g1v1 = true (default behavior)
 
let table = compute_vault_accounts_table_with_g1v1(&[], true).unwrap();
 
let expected_table_with_g1v1 = indoc! {r#"
 
┌─────────────────────────────────────────────────────┐
 
│ SS58 Address/G1v1 public key Crypto Path Name │
 
╞═════════════════════════════════════════════════════╡
 
└─────────────────────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table.to_string(), expected_table_with_g1v1);
 
 
// Test with show_g1v1 = false
 
let table = compute_vault_accounts_table_with_g1v1(&[], false).unwrap();
 
let expected_table_without_g1v1 = indoc! {r#"
 
┌─────────────────────────────────────┐
 
│ SS58 Address Crypto Path Name │
 
╞═════════════════════════════════════╡
 
└─────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table.to_string(), expected_table_without_g1v1);
 
}
 
 
#[test]
 
fn test_compute_vault_accounts_table_with_g1v1() {
 
let account_tree_node = mother_account_tree_node();
 
let g1v1_account_tree_node = mother_g1v1_account_tree_node();
 
let account_tree_nodes = vec![account_tree_node, g1v1_account_tree_node];
 
 
// Test with show_g1v1 = true (default behavior)
 
let table_with_g1v1 =
 
compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true).unwrap();
 
let expected_table_with_g1v1 = indoc! {r#"
 
┌──────────────────────────────────────────────────────────────────────────────────────────┐
 
│ SS58 Address/G1v1 public key Crypto Path Name │
 
╞══════════════════════════════════════════════════════════════════════════════════════════╡
 
│ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV sr25519 <Base> Mother │
 
│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │
 
│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │
 
│ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o //1 <Mother//1> │
 
│ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT //1 <Mother//1//1> │
 
│ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 ed25519 <Base> MotherG1v1 │
 
│ └ G1v1: 86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7 │
 
└──────────────────────────────────────────────────────────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table_with_g1v1.to_string(), expected_table_with_g1v1);
 
 
// Test with show_g1v1 = false
 
let table_without_g1v1 =
 
compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false).unwrap();
 
let expected_table_without_g1v1 = indoc! {r#"
 
┌──────────────────────────────────────────────────────────────────────────────────────────┐
 
│ SS58 Address Crypto Path Name │
 
╞══════════════════════════════════════════════════════════════════════════════════════════╡
 
│ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV sr25519 <Base> Mother │
 
│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │
 
│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │
 
│ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o //1 <Mother//1> │
 
│ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT //1 <Mother//1//1> │
 
│ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 ed25519 <Base> MotherG1v1 │
 
└──────────────────────────────────────────────────────────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1);
 
}
 
 
#[test]
 
fn test_compute_vault_accounts_table_with_g1v1_partial() {
 
let mother = mother_account_tree_node();
 
let child1 = mother.borrow().children[0].clone();
 
let account_tree_nodes = vec![child1];
 
 
// Test with show_g1v1 = true (default behavior)
 
let table_with_g1v1 =
 
compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true).unwrap();
 
let expected_table_with_g1v1 = indoc! {r#"
 
┌─────────────────────────────────────────────────────────────────────────────────────┐
 
│ SS58 Address/G1v1 public key Crypto Path Name │
 
╞═════════════════════════════════════════════════════════════════════════════════════╡
 
│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │
 
│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │
 
└─────────────────────────────────────────────────────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table_with_g1v1.to_string(), expected_table_with_g1v1);
 
 
// Test with show_g1v1 = false
 
let table_without_g1v1 =
 
compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false).unwrap();
 
let expected_table_without_g1v1 = indoc! {r#"
 
┌─────────────────────────────────────────────────────────────────────────────────────┐
 
│ SS58 Address Crypto Path Name │
 
╞═════════════════════════════════════════════════════════════════════════════════════╡
 
│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │
 
│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │
 
└─────────────────────────────────────────────────────────────────────────────────────┘"#
 
};
 
 
assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1);
 
}
}
}
}
}
Loading