1// This file is part of Frontier.
23// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
56// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
1011// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
1516// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
1819#![allow(clippy::format_in_format_args)]
2021use std::{
22 fs,
23 io::{self, Read},
24 path::PathBuf,
25};
2627use serde::de::DeserializeOwned;
28use serde_json::Deserializer;
29// Substrate
30use sp_runtime::traits::Block as BlockT;
3132use super::{DbValue, Operation};
3334pub fn maybe_deserialize_value<B: BlockT>(
35 operation: &Operation,
36 value: Option<&PathBuf>,
37) -> sc_cli::Result<Option<DbValue<B::Hash>>> {
38fn parse_db_values<H: DeserializeOwned, I: Read + Send>(
39 input: I,
40 ) -> sc_cli::Result<Option<DbValue<H>>> {
41let mut stream_deser = Deserializer::from_reader(input).into_iter::<DbValue<H>>();
42if let Some(Ok(value)) = stream_deser.next() {
43Ok(Some(value))
44 } else {
45Err("Failed to deserialize value data".into())
46 }
47 }
4849if let Operation::Create | Operation::Update = operation {
50match &value {
51Some(filename) => parse_db_values::<B::Hash, _>(fs::File::open(filename)?),
52None => {
53let mut buffer = String::new();
54let res = parse_db_values(io::stdin());
55let _ = io::stdin().read_line(&mut buffer);
56 res
57 }
58 }
59 } else {
60Ok(None)
61 }
62}
6364/// Messaging and prompt.
65pub trait FrontierDbMessage {
66fn key_value_error<K: core::fmt::Debug, V: core::fmt::Debug>(
67&self,
68 key: K,
69 value: &V,
70 ) -> sc_cli::Error {
71format!("Key `{key:?}` and Value `{value:?}` are not compatible with this operation").into()
72 }
7374fn key_column_error<K: core::fmt::Debug, V: core::fmt::Debug>(
75&self,
76 key: K,
77 value: &V,
78 ) -> sc_cli::Error {
79format!("Key `{key:?}` and Column `{value:?}` are not compatible with this operation")
80 .into()
81 }
8283fn key_not_empty_error<K: core::fmt::Debug>(&self, key: K) -> sc_cli::Error {
84format!("Operation not allowed for non-empty Key `{key:?}`").into()
85 }
8687#[cfg(not(test))]
88fn confirmation_prompt<K: core::fmt::Debug, V: core::fmt::Debug>(
89&self,
90 operation: &Operation,
91 key: K,
92 existing_value: &V,
93 new_value: &V,
94 ) -> sc_cli::Result<()> {
95println!(
96"{}",
97format!(
98r#"
99 ---------------------------------------------
100 Operation: {:?}
101 Key: {:?}
102 Existing value: {:?}
103 New value: {:?}
104 ---------------------------------------------
105 Type `confirm` and press [Enter] to confirm:
106 "#,
107 operation, key, existing_value, new_value
108 )
109 );
110111let mut buffer = String::new();
112 io::stdin().read_line(&mut buffer)?;
113if buffer.trim() != "confirm" {
114return Err("-- Cancel exit --".into());
115 }
116Ok(())
117 }
118119#[cfg(test)]
120fn confirmation_prompt<K: core::fmt::Debug, V: core::fmt::Debug>(
121&self,
122 _operation: &Operation,
123 _key: K,
124 _existing_value: &V,
125 _new_value: &V,
126 ) -> sc_cli::Result<()> {
127Ok(())
128 }
129}