use sc_cli::Result;
use sc_service::Configuration;
use log::info;
use serde::Serialize;
use std::{env, fs, path::PathBuf};
use super::cmd::StorageParams;
use crate::shared::{Stats, UnderscoreHelper};
static VERSION: &str = env!("CARGO_PKG_VERSION");
static TEMPLATE: &str = include_str!("./weights.hbs");
#[derive(Serialize, Default, Debug, Clone)]
pub(crate) struct TemplateData {
db_name: String,
block_number: String,
runtime_name: String,
version: String,
date: String,
hostname: String,
cpuname: String,
header: String,
args: Vec<String>,
params: StorageParams,
read_weight: u64,
write_weight: u64,
read: Option<(Stats, Stats)>,
write: Option<(Stats, Stats)>,
}
impl TemplateData {
pub fn new(cfg: &Configuration, params: &StorageParams) -> Result<Self> {
let header = params
.header
.as_ref()
.map(|p| std::fs::read_to_string(p))
.transpose()?
.unwrap_or_default();
Ok(TemplateData {
db_name: format!("{}", cfg.database),
runtime_name: cfg.chain_spec.name().into(),
version: VERSION.into(),
date: chrono::Utc::now().format("%Y-%m-%d (Y/M/D)").to_string(),
hostname: params.hostinfo.hostname(),
cpuname: params.hostinfo.cpuname(),
header,
args: env::args().collect::<Vec<String>>(),
params: params.clone(),
..Default::default()
})
}
pub fn set_stats(
&mut self,
read: Option<(Stats, Stats)>,
write: Option<(Stats, Stats)>,
) -> Result<()> {
if let Some(read) = read {
self.read_weight = self.params.weight_params.calc_weight(&read.0)?;
self.read = Some(read);
}
if let Some(write) = write {
self.write_weight = self.params.weight_params.calc_weight(&write.0)?;
self.write = Some(write);
}
Ok(())
}
pub fn set_block_number(&mut self, block_number: String) {
self.block_number = block_number
}
pub fn write(&self, path: &Option<PathBuf>, hbs_template: &Option<PathBuf>) -> Result<()> {
let mut handlebars = handlebars::Handlebars::new();
handlebars.register_helper("underscore", Box::new(UnderscoreHelper));
handlebars.register_escape_fn(|s| -> String { s.to_string() });
let template = match hbs_template {
Some(template) if template.is_file() => fs::read_to_string(template)?,
Some(_) => return Err("Handlebars template is not a valid file!".into()),
None => TEMPLATE.to_string(),
};
let out_path = self.build_path(path);
let mut fd = fs::File::create(&out_path)?;
info!("Writing weights to {:?}", fs::canonicalize(&out_path)?);
handlebars
.render_template_to_write(&template, &self, &mut fd)
.map_err(|e| format!("HBS template write: {:?}", e).into())
}
fn build_path(&self, weight_out: &Option<PathBuf>) -> PathBuf {
let mut path = match weight_out {
Some(p) => PathBuf::from(p),
None => PathBuf::new(),
};
if path.is_dir() || path.as_os_str().is_empty() {
path.push(format!("{}_weights", self.db_name.to_lowercase()));
path.set_extension("rs");
}
path
}
}