Giter VIP home page Giter VIP logo

serde-ini's Introduction

serde-ini

release-badge docs-badge license-badge

serde_ini provides a serde Serializer and Deserializer for the INI format. The format is rather limited, only allowing top level keys to be maps or structs and all values and keys must be in the form of a String. This implementation will try to use ToString and FromStr where appropriate for numeric values. Sequences, tuples, bytes, bools, and some other data types are not supported.

See the documentation for up to date API documentation.

serde-ini's People

Contributors

alexjg avatar arcnmx avatar ehiggs avatar jerry73204 avatar lucab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

serde-ini's Issues

Document `Error`

Apparently serde_ini can't support all data structures. Fine, but would it be possible to know why ? E.g. when serde_ini::to_vec(&item) returns Err(TopLevelMap) it would be convenient to be able to look up in the docs what's the problem.

Multi-line support

The wikipedia page for the INI format states that a backslash followed by a line break indicates a multi-line value.

On the other hand, Python's configparser uses indentation to indicate a multi-line value (see also its documentation on the subject).

It would be great if this crate could support both flavors, maybe via feature flags? e.g. multiline-backslash, multiline-indentation

Context: I am only really interested in Python's flavor because that's needed to correctly parse AWS's CLI config file (see last example for S3 config, which uses multi-line values to emulate nested sections).

Numbers and &str deserialization fails

I was trying to deserialize a u64 and noticed it was failing, even though strings and other objects were working fine. There didn't seem to be any problem with the text being deserialized:

id=61

So I tried making a workaround to investigate:

fn u64_workaround<'de, D>(deserializer: D) -> std::result::Result<u64, D::Error>
where
    D: serde::de::Deserializer<'de>,
{
    use serde::Deserialize;
    <&str>::deserialize(deserializer)?.parse().map_err(serde::de::Error::custom)
}

However this failed, so I eventually tried using a full String

fn u64_workaround<'de, D>(deserializer: D) -> std::result::Result<u64, D::Error>
where
    D: serde::de::Deserializer<'de>,
{
    use serde::Deserialize;
    String::deserialize(deserializer)?.parse().map_err(serde::de::Error::custom)
}

This works, but obviously involves a heap allocation that would seem to be unnecessary.

Regardless, without this workaround, the typical behavior is that integers and real numbers of all types seem to fail.

Allow any level of indentation for section names and key/values

In the spirit of supporting Python's configparser, it would be nice if there was an option to allow any level of indentation for section names and key/values.

Example from the Python doc:

[You can use comments]
# like this
; or this

    [Sections Can Be Indented]
        can_values_be_as_well = True
        does_that_mean_anything_special = False
        purpose = formatting for readability
        multiline_values = are
            handled just fine as
            long as they are indented
            deeper than the first line
            of a value
        # Did I mention we can indent comments, too?

Quoted strings not supported

With #7 merged, there's no way to properly {de,}serialize values that begin or end with whitespace. This behaviour maybe should perhaps be available as an option, but either way supporting quotes like GetPrivateProfileString seems to would help.

How to serialize as a commented out line?

Hi,

I'm still pretty new to serde's concepts, so it might be that there is a very easy solution to my issue.

I want to be able to serialize some lines in my ini files as comments, for example if they contain a default value.

I.e. I might have some setting=100 which should be serialized as ;setting=100, if 100 happens to be the default value for this setting. These "commented out" default values are pretty common in configuration files as a form of self-documentation.

I see that the parser already has a Item::Comment variant that the writer seems to be able to serialize, but I can't find any serialize_comment (or similar) method anywhere and the writer's API is not public.

Any hints how to achieve my goal would bei highly appreciated. I don't mind if it involves a custom serialize_with attribute and function or a manually impl Serialize/r for T.

de: missing de::from_* methods?

I was looking at this crate in order to deserialize some INI files directly into their Rust struct with the usual serde idiom:

let data: MyStruct = serde_ini::from_str(input)?;

However I don't see any of the usual de::from_*() methods. Are they still pending or am I missing something?

I saw you have a public Parser with an iterator interface and several From implementations, but I'm looking for something with direct deserialization and access to sections/values instead.

Files containing byte order mark (BOM) are not supported

Albeit BOMs are redundant for UTF-8, they are still commonly encountered.
I personally tried to parse an UTF-8 file containing a BOM, which lead to time consuming troubleshooting.
It would be great if whenever a potential BOM is present, it is discarded instead of erroring.

EDIT: Albeit this library may choose to ignore it since it doesn't export any direct methods for file IO.

Is this project dying itself alone ?

Hello,

From an external point of view this project has had no commits since 3 years and none of the 3 proposed pull requests has been discussed (one is nearly one year old). So, sadly, it looks like it is dying.

I am wondering if

  • arcnmx the owner of this project is open to enable one or two people to give any help to manage it
  • there is anyone that is willing to help the project

This is a call to move forward on this project so as not to let it die.

ser::Error::OrphanValue

An INI file can only contain top-level keys at the beginning of the file, before the first section starts. This presents a problem if we serialize a section (map/struct type), and then later on encounter another non-section key, so unfortunately depends on the order in which the fields are serialized (generally, this is declaration order). Currently the Serializer will error when this happens with OrphanValue. A simple demonstration:

#[derive(Serialize)]
struct TopLevel {
    data: i32, // a top-level key
    section: HashMap<String, String>, // a [section]
    orphan: i32, // oh no, this needs to be placed above `section`
}

The obvious approach to this I can see would be to avoid writing any sections until the entire type is serialized. Yay allocation, and in the most common case probably means not writing anything out and buffering the whole ini file until the very end. Possibly make this an option when constructing the Serializer?

Maybe with specialization (or code duplication whatever) this could be handled okay when serializing to a buffer (Vec<u8>) where you can just seek+memmove+insert when orphans are encountered. I don't see that working well with files though :(

Support colon as name/value delimiter

Python's configparser supports colons as name/value delimiter.

On another note, it also supports keys without values, but I'm not sure how you'd represent that with serde.

Example from the doc:

[All Values Are Strings]
values like this: 1000000
or this: 3.14159265359
are they treated as numbers? : no
integers, floats and booleans are held as: strings
can use the API to get converted values directly: true

[Multiline Values]
chorus: I'm a lumberjack, and I'm okay
    I sleep all night and I work all day

[No Values]
key_without_value
empty string value here =

Serialize enum fails

Something like:

#[derive(Serialize, Deserialize, Debug)]
struct A {
...
}

#[derive(Serialize, Deserialize, Debug)]
struct B {
...
}

#[derive(Serialize, Deserialize, Debug)]
enum Abc {
A,
B,
}

Do that serde_ini::to_string(); fails, with serde_json the result is like:

{"Tag":{"key":"value",...}}

That could be represent in INI format as:

[Tag]
key=value
...

The error is TopLevelMap like #9 but in this case it's only one level of nesting just to use sections.

auto convert problem with serde `flatten`

https://github.com/Larusso/serde-ini-fail-example/blob/master/src/lib.rs

This example is derived from some experimentation I do at the moment.
It creates three different struct layouts and tries to deserialize the same test data into it.

If you run the tests you will see that the test data_3 (which deserilized into Data3 struct) fails because of the number deserialization issue.

For a better visibility here are the three structs:

#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct Data {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    section_1: Option<Box<FieldData>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    section_2: Option<Box<FieldData>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    section_3: Option<Box<FieldData>>,
}

#[derive(Deserialize, Debug)]
#[serde(transparent)]
pub struct Data2(HashMap<Keys,FieldData>);

#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct Data3 {
    section_1: FieldData,

    #[serde(flatten)]
    components: HashMap<Keys, FieldData>,
}

All three tests in this sample setup use the same struct: FieldData for the fields and the deserializer has no issues with it in the data_1 and data_2 tests.

I hope this helps you

Originally posted by @Larusso in #5 (comment)

Support parsing duplicate sections to Vec<T>

As far as i can tell it's not supported.

Here's an example:

struct User{
    #[serde(rename = "Name")]
    name: String,
}

struct Users{
    #[serde(rename = "User")]
    user: Vec<User>,
};

let raw = r#"
[User]
Name=Foo
[User]
Name=Bar
"#;
// Not supported cause of Vec, but not using Vec makes it fail (accurately) cause of duplicate sections
let data: Users = serde_ini::from_str(&raw).unwrap();

Comments on the same line as a key do not get parsed correctly

Taken this config file for example:

key = value # a comment

serde_ini will parse it as key -> 'value # a comment' instead of key -> value. I would assume comments on the same like would work the same as they do in programming languages. But I might be wrong here ๐Ÿ˜„

Using `#` as a comment character.

I think in the strict interpretation of the ini format as used by Windows, # is not really a comment char (but commenting out a line like #var1=a means #var1 is being set instead of var1). However, in the Python ConfigParser approximation, # are indeed comment characters. Would it be possible to have serde-ini treat # as a comment character?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.