// Copyright 2017, Igor Shaula // Licensed under the MIT License . This file // may not be copied, modified, or distributed // except according to those terms. use self::EncoderState::*; use super::enums::*; use super::transaction::Transaction; use super::RegKey; use std::error::Error; use std::fmt; use std::io; use winapi::shared::minwindef::DWORD; macro_rules! emit_value { ($s:ident, $v:ident) => { match mem::replace(&mut $s.state, Start) { NextKey(ref s) => $s.keys[$s.keys.len() - 1] .set_value(s, &$v) .map_err(EncoderError::IoError), Start => Err(EncoderError::NoFieldName), } }; } macro_rules! no_impl { ($e:expr) => { Err(EncoderError::EncodeNotImplemented($e.to_owned())) }; } #[cfg(feature = "serialization-serde")] mod serialization_serde; #[derive(Debug)] pub enum EncoderError { EncodeNotImplemented(String), SerializerError(String), IoError(io::Error), NoFieldName, KeyMustBeAString, } impl fmt::Display for EncoderError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } } impl Error for EncoderError {} pub type EncodeResult = Result; impl From for EncoderError { fn from(err: io::Error) -> EncoderError { EncoderError::IoError(err) } } #[derive(Debug)] enum EncoderState { Start, NextKey(String), // NextMapKey, } #[derive(Debug)] pub struct Encoder { keys: Vec, tr: Transaction, state: EncoderState, } const ENCODER_SAM: DWORD = KEY_CREATE_SUB_KEY | KEY_SET_VALUE; impl Encoder { pub fn from_key(key: &RegKey) -> EncodeResult { let tr = Transaction::new()?; key.open_subkey_transacted_with_flags("", &tr, ENCODER_SAM) .map(|k| Encoder::new(k, tr)) .map_err(EncoderError::IoError) } fn new(key: RegKey, tr: Transaction) -> Encoder { let mut keys = Vec::with_capacity(5); keys.push(key); Encoder { keys, tr, state: Start, } } pub fn commit(&mut self) -> EncodeResult<()> { self.tr.commit().map_err(EncoderError::IoError) } }