parsing version data

also added a binary for testing and an example file for now
main
Zynh0722 2023-11-23 19:53:57 -08:00
parent 83cf9cf197
commit 5c71e6cb22
4 changed files with 73 additions and 1 deletions

View File

@ -3,6 +3,12 @@ name = "factorio_types"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "testing"
path = "src/bin/testing.rs"
doc = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

Binary file not shown.

14
src/bin/testing.rs Normal file
View File

@ -0,0 +1,14 @@
use std::{fs::File, io::BufReader};
use factorio_types::ModSettings;
fn main() -> anyhow::Result<()> {
let file = File::open("./mod-settings.dat")?;
let buf_reader = BufReader::new(file);
let settings = ModSettings::from_reader(buf_reader)?;
println!("{settings:?}");
Ok(())
}

View File

@ -1,5 +1,11 @@
use std::collections::HashMap;
#![feature(array_chunks)]
#![feature(iter_collect_into)]
use std::{collections::HashMap, io::Read};
use anyhow::{anyhow, Context};
#[derive(Debug)]
pub enum PropertyTree {
None,
Bool(bool),
@ -8,3 +14,49 @@ pub enum PropertyTree {
List(Vec<PropertyTree>),
Dictionary(HashMap<String, PropertyTree>),
}
#[derive(Debug)]
pub struct ModSettings {
pub version: [u16; 4],
pub data: PropertyTree,
}
impl ModSettings {
/// This reads from a reader based on this file specification
/// https://wiki.factorio.com/Mod_settings_file_format
pub fn from_reader<R>(mut reader: R) -> anyhow::Result<ModSettings>
where
R: Read,
{
// Fetching first 8 little endian bytes representing version
// https://wiki.factorio.com/Version_string_format
let mut version_bytes = [0u8; 8];
reader
.read_exact(&mut version_bytes)
.context("Failed trying to get first 8 bytes representing version number")?;
// Grab the null byte that follows the version number
let _padding_byte = reader
.by_ref()
.bytes()
.next()
.ok_or(anyhow!("Unexpected EOF"))
.context("Failed trying to grab null byte that follows version number");
// Mapping pairs of 2 u8s into single le u16s
let mut version_map = version_bytes.array_chunks().map(|b| u16::from_le_bytes(*b));
// Load u16s into an array
let version = [
version_map.next().unwrap(),
version_map.next().unwrap(),
version_map.next().unwrap(),
version_map.next().unwrap(),
];
Ok(ModSettings {
version,
data: PropertyTree::None,
})
}
}