diff --git a/Cargo.lock b/Cargo.lock index 7cc12a5..c7262e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,15 +4,15 @@ version = 3 [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "bstr" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -20,12 +20,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -41,9 +38,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" dependencies = [ "serde", ] @@ -56,31 +53,25 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", ] -[[package]] -name = "libc" -version = "0.2.151" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" - [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mlua" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c81f8ac20188feb5461a73eabb22a34dd09d6d58513535eb587e46bff6ba250" +checksum = "868d02cb5eb97761bbf6bd6922c1c7a88b8ea252bbf43bd8350a0bf8497a1fc0" dependencies = [ "bstr", "erased-serde", @@ -95,9 +86,9 @@ dependencies = [ [[package]] name = "mlua-sys" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc29228347d6bdc9e613dc95c69df2817f755434ee0f7f3b27b57755fe238b7f" +checksum = "2847b42764435201d8cbee1f517edb79c4cca4181877b90047587c89e1b7bce4" dependencies = [ "cc", "cfg-if", @@ -106,9 +97,9 @@ dependencies = [ [[package]] name = "mlua_derive" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f359220f24e6452dd82a3f50d7242d4aab822b5594798048e953d7a9e0314c6" +checksum = "aaade5f94e5829db58791664ba98f35fea6a3ffebc783becb51dc97c7a21abee" dependencies = [ "proc-macro2", "quote", @@ -117,9 +108,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -141,24 +132,24 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -171,9 +162,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -190,32 +181,54 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "syn" -version = "2.0.43" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml-edit-lua" -version = "0.2.1" +version = "0.3.0" dependencies = [ "mlua", "serde", + "toml", "toml_edit", ] @@ -224,14 +237,19 @@ name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -244,9 +262,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "winnow" -version = "0.5.30" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 6059756..aada035 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "toml-edit-lua" -version = "0.2.1" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -17,9 +17,10 @@ name = "toml_edit" crate-type = ["cdylib"] [dependencies] -mlua = { version = "0.9.1", features = ["module", "serialize"] } +mlua = { version = "0.9.6", features = ["module", "serialize"] } serde = "1.0" -toml_edit = "0.19.14" +toml_edit = "0.22.9" +toml = "0.8.12" [target.x86_64-apple-darwin] rustflags = [ diff --git a/README.md b/README.md index fe5c9f0..b0e8643 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,46 @@ Edit toml files while preserving whitespace and formatting from Lua. ## Usage +The `parse` function creates a table with metatable, +which can be converted back to toml (preserving comments) +using `tostring`: + ```lua local toml_content = [[ - [rocks] - # Some commment - "toml-edit" = "1.0.0" +[rocks] +# Some comment +"toml-edit" = "1.0.0" ]] local toml_edit = require("toml-edit") local toml_tbl = toml_edit.parse(toml_content) toml_tbl.rocks["toml-edit"] = "2.0.0" -local new_content = tostring(toml_tbl) +print(tostring(toml_tbl)) +-- outputs: +-- [rocks] +-- # Some comment +-- "toml-edit" = "2.0.0" ``` +The `parse_as_tbl` function parses toml as a regular lua table: + +```lua +local toml_content = [[ +[rocks] +"toml-edit" = "1.0.0" +]] +local toml_edit = require("toml-edit") +local lua_tbl = toml_edit.parse_as_tbl(toml_content) +print(tostring(toml_tbl)) +-- outputs: table: 0x7ff975807668 +``` + +> [!TIP] +> +> - Use `parse` when you need to modify the toml, and you are accessing or +> setting fields by name. +> - Use `parse_as_tbl` when you need to perform operations that don't access +> fields by name (e.g. iterating over key/value pairs). + ## Development ### To run tests: diff --git a/flake.nix b/flake.nix index c69e174..6a49835 100644 --- a/flake.nix +++ b/flake.nix @@ -54,13 +54,16 @@ buildInputs = (with pkgs; [ rust-analyzer + rustc ]) ++ (with pre-commit-hooks.packages.${system}; [ alejandra rustfmt stylua + clippy ]) - ++ oa.buildInputs; + ++ oa.buildInputs + ++ oa.nativeBuildInputs; shellHook = '' ${oa.shellHook} diff --git a/spec/parse_as_tbl_spec.lua b/spec/parse_as_tbl_spec.lua new file mode 100644 index 0000000..b2781a4 --- /dev/null +++ b/spec/parse_as_tbl_spec.lua @@ -0,0 +1,41 @@ +describe("parse_as_tbl", function() + local toml_edit = require("toml_edit") + it("Can parse table", function() + local toml_content = [[ + [rocks."toml-edit"] + version = "1.0.0" + opt = true + [rocks."foo"] + version = "2.0.0" + opt = false + ]] + local result = toml_edit.parse_as_tbl(toml_content) + assert.are.same({ + rocks = { + ["toml-edit"] = { + version = "1.0.0", + opt = true, + }, + foo = { + version = "2.0.0", + opt = false, + }, + }, + }, result) + end) + it("Can loop over fields", function() + local toml_content = [[ + [rocks."toml-edit"] + version = "1.0.0" + opt = true + [rocks."foo"] + version = "2.0.0" + opt = false + ]] + local result = toml_edit.parse_as_tbl(toml_content) + for k, v in pairs(result.rocks) do + assert.is_not_nil(k) + assert.is_not_nil(v) + end + end) +end) diff --git a/spec/toml_edit_spec.lua b/spec/parse_spec.lua similarity index 99% rename from spec/toml_edit_spec.lua rename to spec/parse_spec.lua index 35b3b4b..8e59347 100644 --- a/spec/toml_edit_spec.lua +++ b/spec/parse_spec.lua @@ -1,4 +1,4 @@ -describe("toml-edit", function() +describe("parse", function() local toml_edit = require("toml_edit") it("Can read from key", function() local toml_content = [[ diff --git a/src/lib.rs b/src/lib.rs index 2ed057c..a8946ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,11 @@ use mlua::{ExternalError, Lua, LuaSerdeExt, Result}; use std::cell::RefCell; use std::rc::Rc; -use toml_edit::Document; +use toml_edit::DocumentMut; // TODO: Better error messages -pub fn parse<'lua>(lua: &'lua Lua, document: Rc>) -> Result> +pub fn parse<'lua>(lua: &'lua Lua, document: Rc>) -> Result> where 'lua: 'static, { @@ -159,7 +159,7 @@ pub fn toml_edit(lua: &'static Lua) -> Result { table.set( "parse", lua.create_function(|lua, str: mlua::String| { - let document: Document = match str.to_string_lossy().parse() { + let document: DocumentMut = match str.to_string_lossy().parse() { Ok(document) => document, Err(err) => return Err(err.into_lua_err()), }; @@ -167,5 +167,16 @@ pub fn toml_edit(lua: &'static Lua) -> Result { parse(lua, RefCell::new(document).into()) })?, )?; + table.set( + "parse_as_tbl", + lua.create_function(|lua, str: mlua::String| { + let tbl: toml::Table = match str.to_string_lossy().parse() { + Ok(tbl) => tbl, + Err(err) => return Err(err.into_lua_err()), + }; + + lua.to_value(&tbl) + })?, + )?; Ok(table) }