1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::{commands::HEADING_SANDBOX, utils};
use clap::arg;
use soroban_ledger_snapshot::LedgerSnapshot;
use std::path::{Path, PathBuf};

#[derive(Debug, clap::Args, Clone, Default)]
#[group(skip)]
pub struct Args {
    /// File to persist ledger state, default is `.soroban/ledger.json`
    #[arg(
        long,
        env = "SOROBAN_LEDGER_FILE",
        help_heading = HEADING_SANDBOX,
    )]
    pub ledger_file: Option<PathBuf>,
}

#[derive(thiserror::Error, Debug)]
pub enum Error {
    #[error("reading file {filepath}: {error}")]
    CannotReadLedgerFile {
        filepath: PathBuf,
        error: soroban_ledger_snapshot::Error,
    },

    #[error("committing file {filepath}: {error}")]
    CannotCommitLedgerFile {
        filepath: PathBuf,
        error: soroban_ledger_snapshot::Error,
    },
}

impl Args {
    pub fn read(&self, pwd: &Path) -> Result<LedgerSnapshot, Error> {
        let filepath = self.path(pwd);
        utils::ledger_snapshot_read_or_default(&filepath)
            .map_err(|e| Error::CannotReadLedgerFile { filepath, error: e })
    }

    pub fn write(&self, state: &mut LedgerSnapshot, pwd: &Path) -> Result<(), Error> {
        let filepath = self.path(pwd);

        state
            .write_file(&filepath)
            .map_err(|e| Error::CannotCommitLedgerFile { filepath, error: e })
    }

    pub fn path(&self, pwd: &Path) -> PathBuf {
        if let Some(path) = &self.ledger_file {
            path.clone()
        } else {
            pwd.join("ledger.json")
        }
    }
}