Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding a Map[String, String] should encode keys and values as Yaml Strings, even if some of them look like Ints or other scalars #361

Open
adriaanm opened this issue Nov 4, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@adriaanm
Copy link

adriaanm commented Nov 4, 2024

Example:

scala> Map("a" -> "1").asYaml
val res6: String = "a: 1
"

I would expect the yaml to be

a : "1"

as with #220, this is problematic in kubernetes when encoding e.g. maps of labels.

I managed a workaround for now: s"\"${value}\"".asNode, but it would be nice if

  object ScalarNode {
    def apply(value: String): ScalarNode = new ScalarNode(value, Tag.resolveTag(value))

could be generalised a bit so we can pass the style argument to resolveTag (at least).

However, I would argue that when you encode a Map[String, String] you should only get Yaml Strings in your values. For a Map[String, Any] I could imagine wanting to resolve the tags.

@lbialy
Copy link
Contributor

lbialy commented Nov 4, 2024

Hey Adriaan, it's a more general problem in scala-yaml from what I recall as the initial type was not passed down into the scalars at all. I think I did introduce that for one case and left generalisation of that for a later refactor that did not happen yet (because it should always try to pass what the type was of the thing that got converted into a scalar node so roundtrips yield exactly the same thing).

@adriaanm
Copy link
Author

adriaanm commented Nov 4, 2024

Thanks for taking a look, @lbialy :-) I wouldn't mind creating the AST nodes directly with the explicit types, as I would love to use this over raw yaml, and my devious workaround actually doesn't work (yet):

s"\"1\"".asNode.map(_.asYaml)
val res8: Either[org.virtuslab.yaml.YamlError, String] = Right(1
)

I'll keep looking for a workaround, any hints appreciated :-)

@adriaanm
Copy link
Author

adriaanm commented Nov 4, 2024

Ah, then I saw

// todo escape string using doublequotes
if (tag.contains(Tag.nullTag)) sb.append("!!null")
else sb.append(value)

so now I have this beautiful hack:

  def encodeStringMap(nodes: Map[String, String]): Node = {
    val mappings: Map[Node, Node] = nodes.map { case (key, value) =>
      Node.ScalarNode(key) -> Node.ScalarNode(s"\"$value\"")
    }
    Node.MappingNode(mappings)
  }

(I just have to encode labels for the yaml in a ConfigGroup)

@lbialy lbialy added the bug Something isn't working label Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants