Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if has nix_direnv_version; then
use flake
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Cargo.lock
Thumbs.db
/.idea
/.vscode
.direnv/
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@ case-insensitive = ["unicase"]
# [[A]]
# Key=value
brackets-in-section-names = []
# Allow parsing of nested sections
#
# For example:
# [Section][Subsection]
# key=value
#
# That appears in KDE Configuration files
nested-sections = []
80 changes: 80 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
inputs = {
flake-compat.url = "github:edolstra/flake-compat";

flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};

nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
systems.url = "github:nix-systems/default";
};

outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;

perSystem =
{ pkgs, ... }:
{
devShells.default = pkgs.mkShell {
packages = with pkgs; [
cargo
clippy
rustc
rustfmt
];

strictDeps = true;
};
};
};
}
12 changes: 12 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(import (
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
nodeName = lock.nodes.root.inputs.flake-compat;
in
builtins.fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${
lock.nodes.${nodeName}.locked.rev
}.tar.gz";
sha256 = lock.nodes.${nodeName}.locked.narHash;
}
) { src = ./.; }).shellNix
97 changes: 66 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@

use std::{
borrow::Cow,
char,
error,
char, error,
fmt::{self, Display},
fs::{File, OpenOptions},
io::{self, Read, Seek, SeekFrom, Write},
Expand Down Expand Up @@ -300,53 +299,79 @@ impl Default for WriteOption {
}
}

#[cfg(all(feature = "case-insensitive", not(feature = "nested-sections")))]
pub type SectionKey = Option<UniCase<String>>;
#[cfg(all(feature = "case-insensitive", feature = "nested-sections"))]
pub type SectionKey = Option<Vec<UniCase<String>>>;
#[cfg(all(not(feature = "case-insensitive"), not(feature = "nested-sections")))]
pub type SectionKey = Option<String>;
#[cfg(all(not(feature = "case-insensitive"), feature = "nested-sections"))]
pub type SectionKey = Option<Vec<String>>;

cfg_if! {
if #[cfg(feature = "case-insensitive")] {
/// Internal storage of section's key
pub type SectionKey = Option<UniCase<String>>;
/// Internal storage of property's key
pub type PropertyKey = UniCase<String>;

macro_rules! property_get_key {
($s:expr) => {
&UniCase::from($s)
};
}

macro_rules! property_insert_key {
($s:expr) => {
UniCase::from($s)
};
}

macro_rules! section_key {
($s:expr) => {
$s.map(|s| UniCase::from(s.into()))
};
}

} else {
/// Internal storage of section's key
pub type SectionKey = Option<String>;
/// Internal storage of property's key
pub type PropertyKey = String;

macro_rules! property_get_key {
($s:expr) => {
$s
};
}

macro_rules! property_insert_key {
($s:expr) => {
$s
};
}
}
}

macro_rules! section_key {
($s:expr) => {
$s.map(Into::into)
};
cfg_if! {
if #[cfg(feature = "case-insensitive")] {
cfg_if! {
if #[cfg(feature = "nested-sections")] {
macro_rules! section_key {
($s:expr) => {
$s.map(|s| {
s.split("][")
.map(|part| UniCase::from(part.to_string()))
.collect::<Vec<_>>()
})
};
}
} else {
macro_rules! section_key {
($s:expr) => {
$s.map(|s| UniCase::from(s.into()))
};
}
}
}
} else {
cfg_if! {
if #[cfg(feature = "nested-sections")] {
macro_rules! section_key {
($s:expr) => {
$s.map(|s| s.split("][").map(Into::into).collect::<Vec<_>>())
};
}
} else {
macro_rules! section_key {
($s:expr) => {
$s.map(Into::into)
};
}
}
}
}
}
Expand Down Expand Up @@ -764,8 +789,19 @@ impl Ini {
}

/// Iterate with sections
pub fn sections(&self) -> impl DoubleEndedIterator<Item = Option<&str>> {
self.sections.keys().map(|s| s.as_ref().map(AsRef::as_ref))
pub fn sections(&self) -> impl DoubleEndedIterator<Item = Option<String>> + '_ {
self.sections.keys().map(|key| {
key.as_ref().map(|parts| {
#[cfg(feature = "nested-sections")]
{
parts.join("][")
}
#[cfg(not(feature = "nested-sections"))]
{
parts.clone()
}
})
})
}

/// Set key-value to a section
Expand Down Expand Up @@ -959,12 +995,11 @@ impl Ini {
}

if let Some(ref section) = *section {
write!(
writer,
"[{}]{}",
escape_str(&section[..], opt.escape_policy),
opt.line_separator
)?;
#[cfg(feature = "nested-sections")]
let section_str = format!("[{}]", parts.join("]["));
#[cfg(not(feature = "nested-sections"))]
let section_str = format!("[{}]", escape_str(section, opt.escape_policy));
write!(writer, "{}{}", section_str, opt.line_separator)?;
}
for (k, v) in props.iter() {
let k_str = escape_str(k, opt.escape_policy);
Expand Down
Loading