Add documentation comments for all items

This commit is contained in:
Matthias Schiffer 2023-08-18 19:13:43 +02:00
parent ba86dc8c06
commit 05a8056cbf
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
26 changed files with 576 additions and 42 deletions

View file

@ -1,9 +1,12 @@
//! Functions for reading and deserializing compressed NBT data
use std::{fs::File, io::prelude::*, path::Path};
use anyhow::{Context, Result};
use flate2::read::GzDecoder;
use serde::de::DeserializeOwned;
/// Reads compressed NBT data from a reader and deserializes to a given data structure
pub fn from_reader<R, T>(reader: R) -> Result<T>
where
R: Read,
@ -18,6 +21,7 @@ where
fastnbt::from_bytes(&buf).context("Failed to decode NBT data")
}
/// Reads compressed NBT data from a file and deserializes to a given data structure
pub fn from_file<P, T>(path: P) -> Result<T>
where
P: AsRef<Path>,

View file

@ -1,3 +1,5 @@
//! Helpers and common functions for filesystem access
use std::{
fs::{self, File},
io::{BufReader, BufWriter, Read, Write},
@ -8,15 +10,25 @@ use std::{
use anyhow::{Context, Ok, Result};
use serde::{Deserialize, Serialize};
/// A file metadata version number
///
/// Deserialized metadata with non-current version number are considered invalid
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub struct FileMetaVersion(pub u32);
/// Metadata stored with generated files to track required incremental updates
#[derive(Debug, Serialize, Deserialize)]
struct FileMeta {
/// Version of data described by the FileMeta
version: FileMetaVersion,
/// Timestamp stored with generated data
///
/// This timestamp is always the time of last modification of the inputs
/// that were used to generate the file described by the FileMeta.
timestamp: SystemTime,
}
/// Helper for creating suffixed file paths
fn suffix_name(path: &Path, suffix: &str) -> PathBuf {
let mut file_name = path.file_name().unwrap_or_default().to_os_string();
file_name.push(suffix);
@ -26,24 +38,35 @@ fn suffix_name(path: &Path, suffix: &str) -> PathBuf {
ret
}
/// Derives the filename for temporary storage of data during generation
fn tmpfile_name(path: &Path) -> PathBuf {
suffix_name(path, ".tmp")
}
/// Derives the filename for associated metadata for generated files
fn metafile_name(path: &Path) -> PathBuf {
suffix_name(path, ".meta")
}
/// Creates a directory including all its parents
///
/// Wrapper around [fs::create_dir_all] that adds a more descriptive error message
pub fn create_dir_all(path: &Path) -> Result<()> {
fs::create_dir_all(path)
.with_context(|| format!("Failed to create directory {}", path.display(),))
}
/// Renames a file or directory
///
/// Wrapper around [fs::rename] that adds a more descriptive error message
pub fn rename(from: &Path, to: &Path) -> Result<()> {
fs::rename(from, to)
.with_context(|| format!("Failed to rename {} to {}", from.display(), to.display()))
}
/// Creates a new file
///
/// The contents of the file are defined by the passed function.
pub fn create<T, F>(path: &Path, f: F) -> Result<T>
where
F: FnOnce(&mut BufWriter<File>) -> Result<T>,
@ -60,6 +83,7 @@ where
.with_context(|| format!("Failed to write file {}", path.display()))
}
/// Checks whether the contents of two files are equal
pub fn equal(path1: &Path, path2: &Path) -> Result<bool> {
let mut file1 = BufReader::new(
fs::File::open(path1)
@ -81,6 +105,12 @@ pub fn equal(path1: &Path, path2: &Path) -> Result<bool> {
})
}
/// Creates a new file, temporarily storing its contents in a temporary file
///
/// Storing the data in a temporary file prevents leaving half-written files
/// when the function is interrupted. In addition, the old and new contents of
/// the file are compared if a file with the same name already exists, and the
/// file timestamp is only updated if the contents have changed.
pub fn create_with_tmpfile<T, F>(path: &Path, f: F) -> Result<T>
where
F: FnOnce(&mut BufWriter<File>) -> Result<T>,
@ -104,6 +134,7 @@ where
ret
}
/// Returns the time of last modification for a given file path
pub fn modified_timestamp(path: &Path) -> Result<SystemTime> {
fs::metadata(path)
.and_then(|meta| meta.modified())
@ -115,6 +146,8 @@ pub fn modified_timestamp(path: &Path) -> Result<SystemTime> {
})
}
/// Reads the stored timestamp from file metadata for a file previously written
/// using [create_with_timestamp]
pub fn read_timestamp(path: &Path, version: FileMetaVersion) -> Option<SystemTime> {
let meta_path = metafile_name(path);
let mut file = BufReader::new(fs::File::open(meta_path).ok()?);
@ -127,6 +160,11 @@ pub fn read_timestamp(path: &Path, version: FileMetaVersion) -> Option<SystemTim
Some(meta.timestamp)
}
/// Creates a new file, temporarily storing its contents in a temporary file
/// like [create_with_tmpfile], and storing a timestamp in a metadata file
/// if successful
///
/// The timestamp can be retrieved later using [read_timestamp].
pub fn create_with_timestamp<T, F>(
path: &Path,
version: FileMetaVersion,

View file

@ -1,3 +1,5 @@
//! Input/output functions
pub mod data;
pub mod fs;
pub mod region;

View file

@ -1,3 +1,5 @@
//! Functions for reading and deserializing region data
use std::{
fs::File,
io::{prelude::*, SeekFrom},
@ -10,15 +12,24 @@ use serde::de::DeserializeOwned;
use crate::types::*;
/// Data block size of region data files
///
/// After one header block, the region file consists of one or more consecutive blocks
/// of data for each populated chunk.
const BLOCKSIZE: usize = 4096;
/// Chunk descriptor extracted from region file header
#[derive(Debug)]
struct ChunkDesc {
/// Offset of data block where the chunk starts
offset: u32,
/// Number of data block used by the chunk
len: u8,
/// Coodinates of chunk described by this descriptor
coords: ChunkCoords,
}
/// Parses the header of a region data file
fn parse_header(header: &ChunkArray<u32>) -> Vec<ChunkDesc> {
let mut chunks: Vec<_> = header
.iter()
@ -45,6 +56,7 @@ fn parse_header(header: &ChunkArray<u32>) -> Vec<ChunkDesc> {
chunks
}
/// Decompresses chunk data and deserializes to a given data structure
fn decode_chunk<T>(buf: &[u8]) -> Result<T>
where
T: DeserializeOwned,
@ -63,12 +75,18 @@ where
fastnbt::from_bytes(&decode_buffer).context("Failed to decode NBT data")
}
/// Wraps a reader used to read a region data file
#[derive(Debug)]
pub struct Region<R: Read + Seek> {
/// The wrapper reader
reader: R,
}
impl<R: Read + Seek> Region<R> {
/// Iterates over the chunks of the region data
///
/// The order of iteration is based on the order the chunks appear in the
/// data file.
pub fn foreach_chunk<T, F>(self, mut f: F) -> Result<()>
where
R: Read + Seek,
@ -126,6 +144,7 @@ impl<R: Read + Seek> Region<R> {
}
}
/// Creates a new [Region] from a reader
pub fn from_reader<R>(reader: R) -> Region<R>
where
R: Read + Seek,
@ -133,6 +152,7 @@ where
Region { reader }
}
/// Creates a new [Region] for a file
pub fn from_file<P>(path: P) -> Result<Region<File>>
where
P: AsRef<Path>,

View file

@ -1,3 +1,7 @@
//! Functions for serializing and deserializing MinedMap data structures efficiently
//!
//! Data is serialized using Bincode and compressed using zstd.
use std::{
fs::File,
io::{Read, Write},
@ -10,6 +14,9 @@ use serde::{de::DeserializeOwned, Serialize};
use super::fs;
/// Serializes data and stores it in a file
///
/// A timestamp is stored in an assiciated metadata file.
pub fn write<T: Serialize>(
path: &Path,
value: &T,
@ -29,6 +36,7 @@ pub fn write<T: Serialize>(
})
}
/// Reads data from a file and deserializes it
pub fn read<T: DeserializeOwned>(path: &Path) -> Result<T> {
(|| -> Result<T> {
let mut file = File::open(path)?;