2 unstable releases

0.2.0 Oct 28, 2024
0.1.0 May 30, 2024

#595 in Parser implementations

Download history 5/week @ 2024-09-20 3/week @ 2024-09-27 1/week @ 2024-10-04 170/week @ 2024-10-25 24/week @ 2024-11-01 1/week @ 2024-11-08 82/week @ 2024-11-15 87/week @ 2024-11-22 27/week @ 2024-11-29

200 downloads per month
Used in ludusavi

MIT license

83KB
2K SLoC

Regashii

Regashii is a Rust crate that lets you (de)serialize Windows Regedit *.reg files.

Design

  • This crate aims to be as tolerant as Regedit itself. Regedit will generally ignore lines that it can't handle and even ignore garbage in some positions (e.g., after a key name). When you parse a *.reg file with this crate, the output should include the keys/values that Regedit would actually import.

  • On the other hand, if Regedit would ignore some text, then this crate won't include it in the parsed output. This crate does not preserve formatting or comments.

  • This crate can (de)serialize from string data, or it can read/write the files for you. Regedit uses UTF-8 or UTF-16 depending on the export format, which this crate automatically handles accordingly.

  • This crate attempts to handle various edge cases in a way compatible with Regedit. This includes:

    • Preserving invalid values that Regedit is willing to import (e.g., a hex(4) dword value with the wrong number of bytes)
    • Serializing sz strings values as hex(1) bytes if they contain illegal characters
    • Handling strings which may or may not be null-terminated

    If you find an edge case that's handled poorly, please report it.

  • It also supports registry files from Wine.

Sample

Read

use regashii::{Key, KeyKind, Registry, Value};

let registry = Registry::deserialize_file("sample.reg").unwrap();
for (key_name, key) in registry.keys() {
    match key.kind() {
        KeyKind::Delete => {
            // On import, Regedit would delete this key
        },
        KeyKind::Add => {
            // On import, Regedit would add this key and its values
            for (value_name, value) in key.values() {
                match value {
                    Value::Delete => { /* This value would be deleted */ },
                    Value::Sz(string) => { /* This value would be added */ }
                    _ => { /* and so on */},
                }
            }
        },
        KeyKind::Replace => {
            // On import, Regedit would delete and re-add this key and its values
            for (value_name, value) in key.values() {
                // ...
            }
        },
    }
}

Write

use regashii::{Format, Key, Registry, Value, ValueName};

let registry = Registry::new(Format::Regedit5)
    .with(
        r"HKEY_CURRENT_USER\Software\Foo",
        Key::new()
            .with(ValueName::Default, Value::Sz("some string".to_string()))
            .with("this is a dword", Value::Dword(255)),
    );

registry.serialize_file("sample.reg").unwrap();

Dependencies

~3.5–5MB
~92K SLoC