J'ai trouvé une bibliothèque pour cela https://github.com/daltontf/scala-yaml , mais il semble que peu de développeurs l'utilisent et c'est assez obsolète. Il se peut aussi que ce soit http://www.lag.net/configgy/ si le lien n'était pas mort.
Je me demande quelle est la bibliothèque la plus populaire ou de facto pour travailler avec YAML dans Scala?
SnakeYAML est un analyseur/rendu YAML de haute qualité et activement maintenu pour Java. Vous pouvez bien sûr l'utiliser depuis Scala.
HelicalYAML fournit un wrapper Scala pour SnakeYAML si vous voulez vraiment cette commodité, mais je ne peux pas attester de la qualité ou de la longévité du projet.
Je serais ravi de voir une bibliothèque qui pourrait analyser JSON ou YAML (ou quoi que ce soit - enfichable) à un AST puis construire des objets Scala utilisant des classes de type) Plusieurs bibliothèques JSON fonctionnent comme ça (et bien sûr peuvent également rendre JSON pour des objets utilisant les mêmes classes de types), mais je ne connais pas une telle facilité pour YAML.
Voici un exemple d'utilisation de la liaison de données Jackson YAML .
Tout d'abord, voici notre exemple de document:
name: test
parameters:
"VERSION": 0.0.1-SNAPSHOT
things:
- colour: green
priority: 128
- colour: red
priority: 64
Ajoutez ces dépendances:
libraryDependencies ++= Seq(
"com.fasterxml.jackson.core" % "jackson-core" % "2.1.1",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.1.1",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.1.1",
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % "2.1.1"
)
Voici notre classe la plus externe (les conditions préalables sont une vérification de type goyave et déclenchent une exception si ledit champ n'est pas dans le YAML):
import Java.util.{List => JList, Map => JMap}
import collection.JavaConversions._
import com.fasterxml.jackson.annotation.JsonProperty
class Sample(@JsonProperty("name") _name: String,
@JsonProperty("parameters") _parameters: JMap[String, String],
@JsonProperty("things") _things: JList[Thing]) {
val name = Preconditions.checkNotNull(_name, "name cannot be null")
val parameters: Map[String, String] = Preconditions.checkNotNull(_parameters, "parameters cannot be null").toMap
val things: List[Thing] = Preconditions.checkNotNull(_things, "things cannot be null").toList
}
Et voici l'objet intérieur:
import com.fasterxml.jackson.annotation.JsonProperty
class Thing(@JsonProperty("colour") _colour: String,
@JsonProperty("priority") _priority: Int {
val colour = Preconditions.checkNotNull(_colour, "colour cannot be null")
val priority = Preconditions.checkNotNull(_priority, "priority cannot be null")
}
Enfin, voici comment l'instancier:
val reader = new FileReader("sample.yaml")
val mapper = new ObjectMapper(new YAMLFactory())
val config: Sample = mapper.readValue(reader, classOf[Sample])
Un peu tard pour la fête mais je pense que cette méthode fonctionne de la manière la plus transparente. Cette méthode a:
Code:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.scala.DefaultScalaModule
case class Prop(url: List[String])
// uses Jackson YAML to parsing, relies on SnakeYAML for low level handling
val mapper: ObjectMapper = new ObjectMapper(new YAMLFactory())
// provides all of the Scala goodiness
mapper.registerModule(DefaultScalaModule)
val prop: Prop = mapper.readValue("url: [abc, def]", classOf[Prop])
// prints List(abc, def)
println(prop.url)
Je suis tombé sur moultingyaml aujourd'hui.
MoultingYAML est un wrapper Scala pour SnakeYAML basé sur spray-json.
Cela me semble assez familier, après avoir travaillé des années avec spray-json
. Je pense que cela pourrait correspondre au besoin de @ sihil d'une bibliothèque "convaincante" et "mature" Scala YAML.
Et maintenant, nous avons circe-yaml
https://github.com/circe/circe-yaml
SnakeYAML fournit une Java API pour analyser YAML et rassembler ses structures en classes JVM. Cependant, vous trouverez peut-être le moyen de circe de rassembler en un Scala ADT préférable - en utilisant la spécification ou la dérivation au moment de la compilation plutôt que la réflexion à l'exécution. Cela vous permet d'analyser YAML dans Json et d'utiliser vos décodeurs existants (ou génériques de circe) pour effectuer le triage ADT. Vous pouvez également utiliser l'encodeur de circe pour obtenir un Json, et l'imprimer sur YAML en utilisant cette bibliothèque.
Pour toute autre personne qui traverse cette réponse et cherche de l'aide et des exemples, j'ai trouvé un exemple de base qui utilise snakeYAML J'espère que cela aide. Voici le code:
package yaml
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor
import scala.collection.mutable.ListBuffer
import scala.reflect.BeanProperty
object YamlBeanTest1 {
val text = """
accountName: Ymail Account
username: USERNAME
password: PASSWORD
mailbox: INBOX
imapServerUrl: imap.mail.yahoo.com
protocol: imaps
minutesBetweenChecks: 1
usersOfInterest: [barney, betty, wilma]
"""
def main(args: Array[String]) {
val yaml = new Yaml(new Constructor(classOf[EmailAccount]))
val e = yaml.load(text).asInstanceOf[EmailAccount]
println(e)
}
}
/**
* With the Snakeyaml Constructor approach shown in the main method,
* this class must have a no-args constructor.
*/
class EmailAccount {
@BeanProperty var accountName: String = null
@BeanProperty var username: String = null
@BeanProperty var password: String = null
@BeanProperty var mailbox: String = null
@BeanProperty var imapServerUrl: String = null
@BeanProperty var minutesBetweenChecks: Int = 0
@BeanProperty var protocol: String = null
@BeanProperty var usersOfInterest = new Java.util.ArrayList[String]()
override def toString: String = {
return format("acct (%s), user (%s), url (%s)", accountName, username, imapServerUrl)
}
}
Je n'ai donc pas assez de réputation pour commenter (41 atm) mais j'ai pensé que mon expérience méritait d'être mentionnée.
Après avoir lu ce fil, j'ai décidé d'essayer d'utiliser l'analyseur Jackson YAML parce que je ne voulais pas de constructeurs à zéro argument et qu'il était beaucoup plus lisible. Ce que je ne savais pas, c'est que il n'y a pas de support pour l'héritage (fusion), et il y a un support limité pour la référence d'ancrage (n'est-ce pas que le point entier de YAML ??).
La fusion est expliquée ici .
La référence d'ancrage est expliquée ici . Bien qu'il semble qu'une référence d'ancrage complexe soit prise en charge, je n'ai pas pu la faire fonctionner dans un cas simple.
D'après mon expérience, les bibliothèques JSON pour Scala sont plus matures et plus faciles à utiliser (aucune des approches YAML n'est extrêmement convaincante ou aussi mature que les équivalents JSON lorsqu'il s'agit de traiter des classes de cas ou d'écrire des serialiseurs personnalisés). et désérialiseurs).
En tant que tel, je préfère convertir de YAML en JSON, puis utiliser une bibliothèque JSON. cela peut sembler un peu fou mais ça marche vraiment bien à condition que:
L'approche que j'utilise pour convertir de YAML en JSON s'appuie sur Jackson:
val tree = new ObjectMapper(new YAMLFactory()).readTree(yamlTemplate)
val json = new ObjectMapper()
.writer(new DefaultPrettyPrinter().withoutSpacesInObjectEntries())
.writeValueAsString(tree)