1use ckb_chain_iter::ChainIterator;
2use ckb_jsonrpc_types::BlockView as JsonBlock;
3use ckb_shared::shared::Shared;
4#[cfg(feature = "progress_bar")]
5use indicatif::{ProgressBar, ProgressStyle};
6use std::error::Error;
7use std::fs;
8use std::io;
9use std::io::Write;
10use std::path::PathBuf;
11
12pub struct Export {
14 pub target: PathBuf,
16 pub shared: Shared,
18}
19
20impl Export {
21 pub fn new(shared: Shared, target: PathBuf) -> Self {
23 Export { shared, target }
24 }
25
26 fn file_name(&self) -> String {
28 format!("{}.{}", self.shared.consensus().id, "json")
29 }
30
31 pub fn execute(self) -> Result<(), Box<dyn Error>> {
33 fs::create_dir_all(&self.target)?;
34 self.write_to_json()
35 }
36
37 #[cfg(not(feature = "progress_bar"))]
38 pub fn write_to_json(self) -> Result<(), Box<dyn Error>> {
39 let f = fs::OpenOptions::new()
40 .create_new(true)
41 .read(true)
42 .write(true)
43 .open(self.target.join(self.file_name()))?;
44 let mut writer = io::BufWriter::new(f);
45 let snapshot = self.shared.snapshot();
46
47 for block in ChainIterator::new(snapshot.as_ref()) {
48 let block: JsonBlock = block.into();
49 let encoded = serde_json::to_vec(&block)?;
50 writer.write_all(&encoded)?;
51 writer.write_all(b"\n")?;
52 }
53 Ok(())
54 }
55
56 #[cfg(feature = "progress_bar")]
58 pub fn write_to_json(self) -> Result<(), Box<dyn Error>> {
59 let f = fs::OpenOptions::new()
60 .create_new(true)
61 .read(true)
62 .write(true)
63 .open(self.target.join(self.file_name()))?;
64
65 let mut writer = io::BufWriter::new(f);
66 let snapshot = self.shared.snapshot();
67 let blocks_iter = ChainIterator::new(snapshot.as_ref());
68 let progress_bar = ProgressBar::new(blocks_iter.len());
69 progress_bar.set_style(
70 ProgressStyle::default_bar()
71 .template("[{elapsed_precise}] {bar:50.cyan/blue} {pos:>6}/{len:6} {msg}")
72 .expect("Failed to set progress bar template")
73 .progress_chars("##-"),
74 );
75 for block in blocks_iter {
76 let block: JsonBlock = block.into();
77 let encoded = serde_json::to_vec(&block)?;
78 writer.write_all(&encoded)?;
79 writer.write_all(b"\n")?;
80 progress_bar.inc(1);
81 }
82 progress_bar.finish_with_message("done!");
83 Ok(())
84 }
85}