jprop 0.2.0

no-std parser for java .properties files that actually works
Documentation
  • Coverage
  • 73.02%
    46 out of 63 items documented6 out of 46 items with examples
  • Size
  • Source code size: 66.19 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 5.59 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 15s Average build duration of successful builds.
  • all releases: 15s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • AlexanderSchuetz97

jprop

no-std parser for java .properties files that actually works

Motivation

As everyone should be aware, there are at least a dozen .properties parsers on crates.io; unfortunately, none of them work properly.

A glance into https://en.wikipedia.org/wiki/.properties should reveal that there are many things that can go wrong when trying to parse .properties files.

I have evaluated five different .properties parsers, and none of them are capable of parsing the files I need to parse, so I have come to the conclusion that I sadly have to make my own parser...

Core features

  • 0 dependencies

  • no-std (feature gated, default features use std to allow for decoding of std::io::Read)

  • full UTF-8 and ISO-8859-1 encoding support

    • This means you can parse your file with special symbols without \u escaping them.
      • This is widespread in java resource bundles, and half the parsers on crates.io already fail here.
    • UTF-8 implements a similar fallback to ISO-8859-1 as java does
    • fyi: java 4 and older only supports ISO-8859-1
    • fyi: java 5 to 8 uses ISO-8859-1 by default but can be configured to use UTF-8
    • fyi: java 9 and newer uses UTF-8 by default and uses a fallback to read ISO-8859-1.
  • decoding of 'byte' or 'string' sources

    • byte as in from an io::Read or &[u8] and friends
    • string as in from a &str
  • decoding of comments

    • Yes, in some use-cases this is sadly relevant.
  • document decoding

    • Into Vec<(String, String)> or HashMap<String, String> (std only),
    • Into Vec<Element> Element being an enum, which is either Comment or Key+Value pair.
  • stream decoding

    • Trait-based callback that accepts essentially an fn(Element) -> bool
      • element being an enum, which is either Comment or Key+Value pair.
      • Return false to stop parsing!
  • errors contain position information
    • character index,
    • character in line,
    • line number

Example Usage

Parse key, value as a HashMap<String, String>

use std::collections::HashMap;
use std::fs::File;

pub fn read_test_properties() {
    let mut file = File::open("test.properties").expect("Failed to parse file");
    let data: HashMap<String, String> = jprop::parse_utf8_to_map(&mut file).expect("Failed to parse file");
    //use data here
    //profit?
}

Parse the entire document as a stream.

use jprop::{Element, ParserPosition};
use std::fs::File;

//Your handler would probably have some fields and be more complex.
struct Handler;

impl jprop::PropertyHandler for Handler {
  fn handle(&mut self, position: &ParserPosition, value: Element) -> bool {
    println!("Position {}:{}", position.line+1, position.character_in_line+1);
    match value {
      Element::BlankLine => println!(),
      Element::Comment(text) => println!("{}", text),
      Element::Value(key, value) => println!("{} = {}", key, value),
    }
    true
  }
}

pub fn read_test_properties_as_stream() {
  let mut file = File::open("test.properties").expect("Failed to parse file");
  let mut handler = Handler;
  jprop::parse_utf8(&mut file, &mut handler).expect("Failed to parse file");
  // use handler here
}

Parse from a &str

use std::collections::HashMap;

pub fn read_properties_from_string() {
    let test = "abc=abc\nbcd=bcd\n#..."; //or 'include_str!("some_file.properties");' but that only works with utf-8 files.
    let data: HashMap<String, String> = jprop::parse_str_to_map(test).expect("Failed to parse str");
    //use data here
    //profit?
}