ergo_node_interface/
local_config.rs

1/// Functions related to saving/accessing local data
2/// for interacting with an Ergo Node. (Ip/Port/Api Key)
3use crate::node_interface::{NodeError, NodeInterface, Result};
4use std::fs::File;
5use std::io::prelude::*;
6use std::path::Path;
7use yaml_rust::{Yaml, YamlLoader};
8
9static BAREBONES_CONFIG_YAML: &str = r#"
10# IP Address of the node (default is local, edit if yours is different)
11node_ip: "0.0.0.0"
12# Port that the node is on (default is 9053, edit if yours is different)
13node_port: "9053"
14# API key for the node (edit if yours is different)
15node_api_key: "hello"
16"#;
17
18/// A ease-of-use function which attempts to acquire a `NodeInterface`
19/// from a local file. If the file does not exist, it generates a new
20/// config file, tells the user to edit the config file, and then closes
21/// the running application
22/// This is useful for CLI applications, however should not be used by
23/// GUI-based applications.
24pub fn acquire_node_interface_from_local_config() -> NodeInterface {
25    // `Node-interface.yaml` setup logic
26    if !does_local_config_exist() {
27        println!("Could not find local `node-interface.yaml` file.\nCreating said file with basic defaults.\nPlease edit the yaml file and update it with your node parameters to ensure the CLI app can proceed.");
28        create_new_local_config_file().ok();
29        std::process::exit(0);
30    }
31    // Error checking reading the local node interface yaml
32    if let Err(e) = new_interface_from_local_config() {
33        println!("Could not parse local `node-interface.yaml` file.\nError: {e:?}");
34        std::process::exit(0);
35    }
36    // Create `NodeInterface`
37    new_interface_from_local_config().unwrap()
38}
39
40/// Basic function to check if a local config currently exists
41pub fn does_local_config_exist() -> bool {
42    Path::new("node-interface.yaml").exists()
43}
44
45/// Create a new `node-interface.config` with the barebones yaml inside
46pub fn create_new_local_config_file() -> Result<()> {
47    let file_path = Path::new("node-interface.yaml");
48    if !file_path.exists() {
49        let mut file = File::create(file_path).map_err(|_| {
50            NodeError::YamlError("Failed to create `node-interface.yaml` file".to_string())
51        })?;
52        file.write_all(&BAREBONES_CONFIG_YAML.to_string().into_bytes())
53            .map_err(|_| {
54                NodeError::YamlError(
55                    "Failed to write to local `node-interface.yaml` file".to_string(),
56                )
57            })?;
58    }
59    Err(NodeError::YamlError(
60        "Local `node-interface.yaml` already exists.".to_string(),
61    ))
62}
63
64/// Uses the config yaml provided to create a new `NodeInterface`
65pub fn new_interface_from_yaml(config: Yaml) -> Result<NodeInterface> {
66    let ip = config["node_ip"].as_str().ok_or_else(|| {
67        NodeError::YamlError("`node_ip` is not specified in the provided Yaml".to_string())
68    })?;
69    let port = config["node_port"].as_str().ok_or_else(|| {
70        NodeError::YamlError("`node_port` is not specified in the provided Yaml".to_string())
71    })?;
72    let api_key = config["node_api_key"].as_str().ok_or_else(|| {
73        NodeError::YamlError("`node_api_key` is not specified in the provided Yaml".to_string())
74    })?;
75    NodeInterface::new(api_key, ip, port)
76}
77
78/// Opens a local `node-interface.yaml` file and uses the
79/// data inside to create a `NodeInterface`
80pub fn new_interface_from_local_config() -> Result<NodeInterface> {
81    let yaml_str = std::fs::read_to_string("node-interface.yaml").map_err(|_| {
82        NodeError::YamlError("Failed to read local `node-interface.yaml` file".to_string())
83    })?;
84    let yaml = YamlLoader::load_from_str(&yaml_str).unwrap()[0].clone();
85    new_interface_from_yaml(yaml)
86}