1

I have a configuration file in hjson format. There are a lot of values and comments in this file.

Simplified file looks like this:

{
  # Comments
  # comments
  Variants: [v1, v2, v3]

  # Comments
  # comments
  Values: { v1: ["asd"]}

  # Comments
  # comments
  Some: [p1, p2]

  # Comments
  # comments
  Name: Champion

  # Comments
  # comments
  Something: [a,b,c]

  # etc
  # ...
}

I only need to make changes to one array: Variants (I need to add values there).

The rest remains unchanged.

Now I'm doing this by parsing using serde_hjson (nu_json), working with the config as an object and writing the modified object back to the file as json.

As a result, all comments are lost.

Please tell me how to do what I need without losing the comments in the file.

Comments can be very diverse - each user has their own.

P.S.: this configuration file format was not chosen by me, this is another application.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
Evgeny
  • 45
  • 6
  • The `serde_hjson` crate's [`Value`](https://hjson.github.io/hjson-rust/serde_hjson/value/enum.Value.html) not having a comment variant does not make me hopeful that you can keep comments with this library. (But the docs state nothing about it.) – Caesar Dec 09 '22 at 23:12

1 Answers1

0

Update - this approach only works if no comments are inside of the array:

If performance is not an issue, you could use the following hack as a quick and dirty solution:

  1. parse the original hjson-file and writing it to a tmp-file "tmp1.hjson" without making changes
  2. parse the original hjson-file, make the changes you need and write to "tmp2.hjson"
  3. read the contents of both files and store the diff (store both oldContent and newContent, but only what has changed)
  4. In the original hjson-file, replace oldContent with newContent. Don't use serde_hjson parser for this - just read the file as text, make the replacement on the content string and overwrite the content of the file.

I am not fluent in Rust, but maybe steps 1 and 2 are possible without creating an actual file.

  • Hjson is a very "imprecise" format. There can be a lot of spaces, line feeds, comments inside the constructions. And all this is lost when parsing into strict json. I.e., the fragment that was in the original hjson will not match the same fragment (without modifications) in json. Therefore, it is problematic to make such a replacement. – Evgeny Dec 11 '22 at 10:37
  • you're right, I oversaw that. It would be helpful if you could add some examples of hard cases. Like in this question: https://stackoverflow.com/q/74756859/5677130 – Martin del Necesario Dec 11 '22 at 10:45
  • I see no easy way of doing it then...I see the main problem in the comments that can appear anywhere. You will have to write your own parser where you keep track of opening and closing chars for comments ([`#`, `endOfLine`], [`//`, `endOfLine`], [`/*`, `*/`]) as well as opening and closing chars for strings. Then you'd have to create a stack that starts when you found `Variants: ` and continue until your stack is empty. And you have to consider if you are currently inside a comment.... – Martin del Necesario Dec 11 '22 at 10:51
  • Yes, I also think I will have to do it this way... – Evgeny Dec 11 '22 at 11:53