// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Polkadot is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . use alloc::vec::Vec; use parity_scale_codec::{Encode, Decode}; #[derive(Encode, Decode)] #[codec(encode_bound())] #[codec(decode_bound())] pub struct DoubleEncoded { encoded: Vec, #[codec(skip)] decoded: Option, } impl Clone for DoubleEncoded { fn clone(&self) -> Self { Self { encoded: self.encoded.clone(), decoded: None } } } impl Eq for DoubleEncoded { } impl PartialEq for DoubleEncoded { fn eq(&self, other: &Self) -> bool { self.encoded.eq(&other.encoded) } } impl core::fmt::Debug for DoubleEncoded { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.encoded.fmt(f) } } impl From> for DoubleEncoded { fn from(encoded: Vec) -> Self { Self { encoded, decoded: None } } } impl DoubleEncoded { pub fn into(self) -> DoubleEncoded { DoubleEncoded::from(self) } pub fn from(e: DoubleEncoded) -> Self { Self { encoded: e.encoded, decoded: None, } } pub fn as_ref(&self) -> Option<&T> { self.decoded.as_ref() } } impl DoubleEncoded { pub fn ensure_decoded(&mut self) -> Result<&T, ()> { if self.decoded.is_none() { self.decoded = T::decode(&mut &self.encoded[..]).ok(); } self.decoded.as_ref().ok_or(()) } pub fn take_decoded(&mut self) -> Result { self.decoded.take().or_else(|| T::decode(&mut &self.encoded[..]).ok()).ok_or(()) } pub fn try_into(mut self) -> Result { self.ensure_decoded()?; self.decoded.ok_or(()) } }