1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! A library for parsing FreeDesktop entry files. These files are used in the
//! [Desktop Entry
//! files](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html),
//! [Icon Theme index
//! files](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html),
//! and [Systemd unit
//! files](https://www.freedesktop.org/software/systemd/man/systemd.unit.html).
//! They are similar to ini files but are distinct enough that an ini parse
//! would not work.
//!
//! This library slightly breaks from the FreeDesktop spec by allowing duplicate sections
//! and keys because some common users like systemd use duplicate keys. This is why attribute
//! values are lists. Duplicate sections are merged.
//!
//! This library does join continued lines. An attribute value line ending in a backslash (\) will
//! have the content of the next line starting at the first non-whitespace character merged into
//! one string. It does not modify attribute values in any other way, like replacing escape
//! sequences like `\r` and `\n` with their respective real values.
//!
//! # Struct of Freedesktop Entry Files
//!
//! Freedesktop entry files are split up into section, each with a header in the
//! form `[NAME]`. Each section has attributes, which are key value pairs,
//! separated by and `=`. Some attributes have parameters. These are values
//! between `[]` and the end of the attribute name. These are often use for
//! localization.
//!
//! Here is a snippet from `firefox.desktop`
//!
//! ```ignore
//! [Desktop Entry]
//! Version=1.0
//! Name=Firefox
//! GenericName=Web Browser
//! GenericName[ar]=متصفح ويب
//! GenericName[ast]=Restolador Web
//! GenericName[bn]=ওয়েব ব্রাউজার
//! GenericName[ca]=Navegador web
//! Exec=/usr/lib/firefox/firefox %u
//! Icon=firefox
//!
//! [Desktop Action new-window]
//! Name=New Window
//! Name[ach]=Dirica manyen
//! Name[af]=Nuwe venster
//! Name[an]=Nueva finestra
//! Exec=/usr/lib/firefox/firefox --new-window %u
//! ```
//!
//! The first section is called `Desktop Entry`. Is has many attributes
//! including `Name` which is `Firefox`. The `GenericName` attributes has a
//! param. The default value is in English but there are also values with a
//! parameter for different locales.
//!
//! # APIs
//!
//! This library has two APIs, a high level API and a low level byte oriented API.
//! The main entry point for the high level API is [`Entry`] and the entry point for
//! the lower level API is the [`low_level::parse_entry`] function.
//!
//! ## High Level API
//!
//! As example input lets use the contents of `sshd.service`
//! ```ignore
//! [Unit]
//! Description=OpenSSH Daemon
//! Wants=sshdgenkeys.service
//! After=sshdgenkeys.service
//! After=network.target
//!
//! [Service]
//! ExecStart=/usr/bin/sshd -D
//! ExecReload=/bin/kill -HUP $MAINPID
//! KillMode=process
//! Restart=always
//!
//! [Install]
//! WantedBy=multi-user.target
//! ```
//!
//! For example, to print the start command we could do this:
//! ```
//! # #[cfg(miri)] fn main() {}
//! # #[cfg(not(miri))]
//! # fn main() -> Result<(), std::io::Error> {
//! use freedesktop_entry_parser::parse_entry;
//!
//! let entry = parse_entry("./test_data/sshd.service")?;
//! let start_cmd = entry
//! .section("Service")
//! .expect("Section Service doesn't exist")
//! .attr("ExecStart")
//! .get(0)
//! .expect("Attribute ExecStart doesn't exist");
//! println!("{}", start_cmd);
//!
//! # Ok::<(), std::io::Error>(())
//! # }
//! ```
//! ## Low Level API
//!
//! The [`low_level`] module exposes a less ergonomic but is a *mostly* zero-copy API that is used
//! by the higher level API in this module. You may want to use this API if you need to squeeze
//! out all of the performance you can.
pub use *;