ebarnard / rust-plist

A rusty plist parser.
MIT License
71 stars 42 forks source link

Parsing a plist with `Value::from` that is `&str` results in the entire plist represented as a single `String` #86

Closed ReagentX closed 1 year ago

ReagentX commented 2 years ago

Sample code:

let plist_str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
    <dict>
        <key>$archiver</key>
        <string>NSKeyedArchiver</string>
        <key>$objects</key>
        <array>
            <null/>
            <string>Test</string>
            <dict>
                <key>Example</key>
                <dict>
                    <key>CF$UID</key>
                    <integer>1</integer>
                </dict>
            </dict>
        </array>
        <key>$top</key>
        <dict>
        <key>root</key>
        <dict>
            <key>CF$UID</key>
            <integer>2</integer>
        </dict>
        </dict>
        <key>$version</key>
        <integer>100000</integer>
    </dict>
</plist>
";
let plist = Value::from(plist_str);
println!("{:?}", plist);

Output:

String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n        <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n        <plist version=\"1.0\">\n            <dict>\n                <key>$archiver</key>\n                <string>NSKeyedArchiver</string>\n                <key>$objects</key>\n                <array>\n                    <null/>\n                    <string>Test</string>\n                    <dict>\n                        <key>Example</key>\n                        <dict>\n                            <key>CF$UID</key>\n                            <integer>1</integer>\n                        </dict>\n                    </dict>\n                </array>\n                <key>$top</key>\n                <dict>\n                <key>root</key>\n                <dict>\n                    <key>CF$UID</key>\n                    <integer>2</integer>\n                </dict>\n                </dict>\n                <key>$version</key>\n                <integer>100000</integer>\n            </dict>\n        </plist>\n        ")

Opening the same plist as a file (using Value::from_reader) works as expected.

ebarnard commented 2 years ago

There are a couple of things here.

It looks like Value is missing Value::from_bytes to mirror plist::from_bytes. That should be implemented. There should also be a doc example of what to do if you have an XML plist string.

The From impl for str is working as intended, although clearly its semantics aren't great. However, it couldn't be used to construct a plist from an XML plst string, as From impls are infallible.

As for why it exists, those conversions are pretty much copied from serde_json which is the crate people are most likely familiar with.

ebarnard commented 1 year ago

I'm going to close this as working as intended.

ReagentX commented 1 year ago

Thanks for all your work on this library, it was invaluable for my work on imessage-exporter!