eml_nl/lib.rs
1//! EML (Election Markup Language) library written by the
2//! [Kiesraad](https://www.kiesraad.nl/) (the Dutch Electoral Council) for
3//! parsing and writing EML_NL documents written in safe Rust code only.
4//!
5//! This library sometimes uses EML and EML_NL interchangeably, but only EML_NL
6//! is supported. For details of the EML_NL standard, see the
7//! [Kiesraad EML_NL repository](https://github.com/kiesraad/EML_NL/).
8//!
9//! This crate only parses and writes EML documents in memory, it does not
10//! support streaming parsing or writing. This was a design decision to keep
11//! the code simple and maintainable, and it is expected that EML documents will
12//! generally not be extremely large. Up to a few megabytes were expected, but
13//! larger documents will work fine as long as enough memory is available.
14//! Expect somewhere between 1.2 and 2.0 times the original document size
15//! depending on the contents of the file.
16//!
17//! ## Getting started
18//! The main entrypoints for this crate are the [`EML`](crate::documents::EML)
19//! enum for parsing any EML document. You can also use the specific structs
20//! for specific EML_NL documents, such as
21//! [`ElectionDefinition`](crate::documents::election_definition::ElectionDefinition)
22//! for a 110a EML document. The best reference for which documents are supported
23//! are the variants in the [`EML`](crate::documents::EML) enum.
24//!
25//! Reading of EML documents is done through the [`EMLRead`](crate::io::EMLRead)
26//! trait, while writing is done through the [`EMLWrite`](crate::io::EMLWrite)
27//! trait. So to read an EML document and directly write it back to XML you
28//! could do this:
29//!
30//! ```rust
31//! use eml_nl::{documents::EML, io::{EMLRead, EMLWrite}};
32//! let xml = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/test-emls/polling_stations/eml110b_polling_stations_construction_output.eml.xml"));
33//! let eml_doc = EML::parse_eml(xml, eml_nl::io::EMLParsingMode::Strict).unwrap();
34//! let xml_output = eml_doc.write_eml_root_str(true, true).unwrap();
35//! assert_eq!(xml_output, xml);
36//! ```
37//!
38//! In this example we also see [`EMLParsingMode`](crate::io::EMLParsingMode)
39//! being used. This enum defines how strict parsing of several values and elements
40//! should be. Take a look at the documenation for the enum for more information.
41//!
42//! Many times when parsing specific values from EML documents, such as dates or
43//! identifiers, depending on the parsing mode, the values may be stored as the
44//! raw string or the parsed value. To handle this, we use the
45//! [`StringValue`](crate::utils::StringValue) type, which can contain either
46//! the raw string or the parsed value. Take a look at the documentation for
47//! that type for more information.
48//!
49//! In general it should not be necessary to use the string values directly
50//! unless you are doing something with values that cannot be parsed or where
51//! you don't really care about the actual value. In most cases you should let
52//! the library handle the parsing of raw strings.
53//!
54//! ## Error handling
55//! During parsing and writing of EML documents, various errors can occur.
56//! These are represented by the [`EMLError`] type, which contains an
57//! [`EMLErrorKind`] indicating the actual error type.
58//!
59//! When parsing, the library will attempt to provide location information
60//! whenever possible for errors. This is done through the use of the
61//! [`Span`](crate::io::Span) type, which indicates the byte range in the
62//! original XML document where the error occurred. Other operations (including
63//! writing documents) generally will not have this location information
64//! available.
65
66// This crate must only use safe Rust code.
67#![forbid(unsafe_code)]
68// All public items must have some kinds of documentation.
69#![forbid(missing_docs)]
70
71pub mod common;
72pub mod documents;
73mod error;
74pub mod io;
75pub mod utils;
76
77pub use error::*;
78
79/// Supported EML schema version
80pub(crate) const EML_SCHEMA_VERSION: &str = "5";
81
82/// Namespace URI for the EML standard
83pub(crate) const NS_EML: &str = "urn:oasis:names:tc:evs:schema:eml";
84
85/// Namespace URI for the Kiesraad expansions on the EML standard
86pub(crate) const NS_KR: &str = "http://www.kiesraad.nl/extensions";
87
88/// Namespace URI for the eXtensible Address Language (xAL)
89pub(crate) const NS_XAL: &str = "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0";
90
91/// Namespace URI for the eXtensible Name Language (xNL)
92pub(crate) const NS_XNL: &str = "urn:oasis:names:tc:ciq:xsdschema:xNL:2.0";
93
94/// Namespace URI for XML Digital Signatures
95pub(crate) const NS_DS: &str = "http://www.w3.org/2000/09/xmldsig#";
96
97// /// Namespace URI for XML Schema
98// pub(crate) const NS_XMLNS: &str = "http://www.w3.org/2000/xmlns/";
99// /// Namespace URI for XML
100// pub(crate) const NS_XML: &str = "http://www.w3.org/XML/1998/namespace";