Skip to content
Snippets Groups Projects

Json output

Open poka requested to merge json-output into master
1 unresolved thread

Files

+ 282
0
@@ -4,6 +4,7 @@ use crate::entities::vault_account::AccountTreeNode;
use crate::keys::CryptoScheme;
use crate::utils::GcliError;
use comfy_table::{Cell, Table};
use serde::Serialize;
use std::cell::RefCell;
use std::rc::Rc;
use std::str;
@@ -142,6 +143,89 @@ pub fn compute_vault_accounts_row_with_g1v1(
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)]
mod tests {
mod vault_accounts_table_tests {
@@ -317,4 +401,202 @@ mod tests {
assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1);
}
}
mod vault_accounts_json_view_tests {
use crate::commands::vault::display::{compute_vault_accounts_json, VaultAccountView};
use crate::entities::vault_account::tests::account_tree_node_tests::{
mother_account_tree_node, mother_g1v1_account_tree_node,
};
use log::{debug, LevelFilter};
use pretty_assertions::assert_eq;
use serde_json::{json, Value};
/// This allows to activate debug logs for the tests (to retrieve ACTUAL values in logs)
#[allow(dead_code)]
fn init_logger_in_debug() {
let _ = env_logger::builder()
.is_test(true)
.filter_level(LevelFilter::Debug)
.try_init();
}
#[test]
fn test_compute_vault_accounts_json_view_with_g1v1() {
// init_logger_in_debug();
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 view_with_g1v1 = compute_vault_accounts_json(&account_tree_nodes, true);
let expected_json_with_g1v1 = json! ([
{
"address": "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV",
"crypto_scheme": "sr25519",
"path": "<Base>",
"name": "Mother",
"g1v1_public_key": null,
"children": [
{
"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
"crypto_scheme": null,
"path": "//0",
"name": "Child 1",
"g1v1_public_key": null,
"children": [
{
"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
"crypto_scheme": null,
"path": "//0",
"name": "Grandchild 1",
"g1v1_public_key": null,
"children": []
}
]
},
{
"address": "5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
"crypto_scheme": null,
"path": "//1",
"name": "<Mother//1>",
"g1v1_public_key": null,
"children": [
{
"address": "5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT",
"crypto_scheme": null,
"path": "//1",
"name": "<Mother//1//1>",
"g1v1_public_key": null,
"children": []
}
]
}
]
},
{
"address": "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4",
"crypto_scheme": "ed25519",
"path": "<Base>",
"name": "MotherG1v1",
"g1v1_public_key": "86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7",
"children": [],
}
]);
assert_eq!(get_json_value(&view_with_g1v1), expected_json_with_g1v1);
// Test with show_g1v1 = false
let view_without_g1v1 = compute_vault_accounts_json(&account_tree_nodes, false);
let expected_json_without_g1v1 = json! ([
{
"address": "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV",
"crypto_scheme": "sr25519",
"path": "<Base>",
"name": "Mother",
"g1v1_public_key": null,
"children": [
{
"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
"crypto_scheme": null,
"path": "//0",
"name": "Child 1",
"g1v1_public_key": null,
"children": [
{
"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
"crypto_scheme": null,
"path": "//0",
"name": "Grandchild 1",
"g1v1_public_key": null,
"children": []
}
]
},
{
"address": "5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
"crypto_scheme": null,
"path": "//1",
"name": "<Mother//1>",
"g1v1_public_key": null,
"children": [
{
"address": "5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT",
"crypto_scheme": null,
"path": "//1",
"name": "<Mother//1//1>",
"g1v1_public_key": null,
"children": []
}
]
}
]
},
{
"address": "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4",
"crypto_scheme": "ed25519",
"path": "<Base>",
"name": "MotherG1v1",
"g1v1_public_key": null,
"children": []
}
]);
assert_eq!(
get_json_value(&view_without_g1v1),
expected_json_without_g1v1
);
}
#[test]
fn test_compute_vault_accounts_json_view_with_g1v1_partial() {
// init_logger_in_debug();
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 view_with_g1v1 = compute_vault_accounts_json(&account_tree_nodes, true);
let expected_json_with_g1v1_unused = json! ([
{
"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
"crypto_scheme": null,
"path": "//0",
"name": "Child 1",
"g1v1_public_key": null,
"children": [
{
"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
"crypto_scheme": null,
"path": "//0",
"name": "Grandchild 1",
"g1v1_public_key": null,
"children": [],
}
]
}
]);
assert_eq!(
get_json_value(&view_with_g1v1),
expected_json_with_g1v1_unused
);
// Test with show_g1v1 = false
let view_without_g1v1 = compute_vault_accounts_json(&account_tree_nodes, false);
assert_eq!(
get_json_value(&view_without_g1v1),
expected_json_with_g1v1_unused
);
}
fn get_json_value(views: &Vec<VaultAccountView>) -> Value {
let view_json_string = serde_json::to_string_pretty(&views).unwrap();
debug!("Actual JSON:\n{}", view_json_string);
let view_json_value: Value = serde_json::from_str(&view_json_string).unwrap();
view_json_value
}
}
}
Loading