1 // Copyright 2024 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // TODO: remove in next change. 6 #![allow(dead_code)] 7 8 use std::fs::File; 9 use std::io::BufReader; 10 use std::io::BufWriter; 11 use std::io::Write; 12 use std::path::PathBuf; 13 14 use crate::RutabagaError; 15 use crate::RutabagaResult; 16 17 pub struct RutabagaSnapshotWriter { 18 dir: PathBuf, 19 } 20 21 impl RutabagaSnapshotWriter { from_existing(directory: impl Into<PathBuf>) -> Self22 pub fn from_existing(directory: impl Into<PathBuf>) -> Self { 23 Self { 24 dir: directory.into(), 25 } 26 } 27 get_path(&self) -> PathBuf28 pub fn get_path(&self) -> PathBuf { 29 self.dir.clone() 30 } 31 add_namespace(&self, name: &str) -> RutabagaResult<Self>32 pub fn add_namespace(&self, name: &str) -> RutabagaResult<Self> { 33 let directory = self.dir.join(name); 34 35 std::fs::create_dir(&directory).map_err(RutabagaError::IoError)?; 36 37 Ok(Self::from_existing(directory)) 38 } 39 add_fragment<T: serde::Serialize>(&self, name: &str, t: &T) -> RutabagaResult<()>40 pub fn add_fragment<T: serde::Serialize>(&self, name: &str, t: &T) -> RutabagaResult<()> { 41 let fragment_path = self.dir.join(name); 42 let fragment_file = File::options() 43 .write(true) 44 .create_new(true) 45 .open(fragment_path) 46 .map_err(|e| { 47 RutabagaError::SnapshotError(format!("failed to add fragment {}: {}", name, e)) 48 })?; 49 let mut fragment_writer = BufWriter::new(fragment_file); 50 serde_json::to_writer(&mut fragment_writer, t).map_err(|e| { 51 RutabagaError::SnapshotError(format!("failed to write fragment {}: {}", name, e)) 52 })?; 53 fragment_writer.flush().map_err(|e| { 54 RutabagaError::SnapshotError(format!("failed to flush fragment {}: {}", name, e)) 55 })?; 56 Ok(()) 57 } 58 } 59 60 pub struct RutabagaSnapshotReader { 61 dir: PathBuf, 62 } 63 64 impl RutabagaSnapshotReader { from_existing(directory: impl Into<PathBuf>) -> RutabagaResult<Self>65 pub fn from_existing(directory: impl Into<PathBuf>) -> RutabagaResult<Self> { 66 let directory = directory.into(); 67 68 if !directory.as_path().exists() { 69 return Err(RutabagaError::SnapshotError(format!( 70 "{} does not exist", 71 directory.display() 72 ))); 73 } 74 75 Ok(Self { dir: directory }) 76 } 77 get_path(&self) -> PathBuf78 pub fn get_path(&self) -> PathBuf { 79 self.dir.clone() 80 } 81 get_namespace(&self, name: &str) -> RutabagaResult<Self>82 pub fn get_namespace(&self, name: &str) -> RutabagaResult<Self> { 83 let directory = self.dir.join(name); 84 Self::from_existing(directory) 85 } 86 get_fragment<T: serde::de::DeserializeOwned>(&self, name: &str) -> RutabagaResult<T>87 pub fn get_fragment<T: serde::de::DeserializeOwned>(&self, name: &str) -> RutabagaResult<T> { 88 let fragment_path = self.dir.join(name); 89 let fragment_file = File::open(fragment_path).map_err(|e| { 90 RutabagaError::SnapshotError(format!("failed to get fragment {}: {}", name, e)) 91 })?; 92 let mut fragment_reader = BufReader::new(fragment_file); 93 serde_json::from_reader(&mut fragment_reader).map_err(|e| { 94 RutabagaError::SnapshotError(format!("failed to read fragment {}: {}", name, e)) 95 }) 96 } 97 } 98