https://github.com/losizm/shampoo
The YAML library for Scala
https://github.com/losizm/shampoo
scala yaml
Last synced: 2 months ago
JSON representation
The YAML library for Scala
- Host: GitHub
- URL: https://github.com/losizm/shampoo
- Owner: losizm
- License: apache-2.0
- Created: 2024-01-01T20:06:10.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-05T09:50:12.000Z (about 1 year ago)
- Last Synced: 2025-10-09T08:23:37.204Z (9 months ago)
- Topics: scala, yaml
- Language: Scala
- Homepage:
- Size: 2.97 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Shampoo
[](https://central.sonatype.com/search?q=g:com.github.losizm%20a:shampoo_3)
The YAML library for Scala.
## Getting Started
To get started, add **Shampoo** to your project:
```scala
libraryDependencies += "com.github.losizm" %% "shampoo" % "1.0.0"
```
The underlying YAML processor is provided by [SnakeYAML Engine](https://github.com/snakeyaml/snakeyaml-engine/),
so it'll be added transitively.
## Lather Up!
Reading and writing are powered by `YamlConstructor` and `YamlRepresenter`.
Library-provided implementations are available for working with standard types,
such as `String`, `Int`, etc. You must define custom implementations to work
with other types.
```scala
import scala.language.implicitConversions
import shampoo.yaml.{ *, given }
case class User(id: Int, name: String, groups: Seq[String])
// Define how to construct User from YAML
given YamlConstructor[User] with
def construct(yaml: YamlNode) =
User(
yaml("id"),
yaml("name"),
yaml("groups")
)
// Load YAML mapping
val yaml = Yaml.load("""
id: 1000
name: lupita
groups:
- lupita
- admin
- sudoers
""")
// Construct and verify
val user = yaml.as[User]
assert(user.id == 1000)
assert(user.name == "lupita")
assert(user.groups == Seq("lupita", "admin", "sudoers"))
// Define how to represent YAML from User
given YamlRepresenter[User] with
def represent(user: User) =
Yaml.map(
"id" -> user.id,
"name" -> user.name,
"groups" -> user.groups
)
// Represent and verify
val yamlUser = Yaml.toYaml(user)
assert(yamlUser.getInt("id") == 1000)
assert(yamlUser.getString("name") == "lupita")
assert(yamlUser("groups").as[Seq[String]] == Seq("lupita", "admin", "sudoers"))
```
Special implementations are available for working with collections. For example,
if `YamlConstructor[User]` is defined, `YamlConstructor[Seq[User]]` can be
inferred. The same applies to `YamlRepresenter[User]` and `YamlRepresenter[Seq[User]]`.
```scala
// Load YAML sequence
val yaml = Yaml.load("""
- id: 0
name: root
groups:
- root
- id: 1000
name: lupita
groups:
- lupita
- admin
- sudoers
""")
// Read YamlSequence as Seq[User]
val users = yaml.as[Seq[User]]
assert { users(0) == User(0, "root", Seq("root")) }
assert { users(1) == User(1000, "lupita", Seq("lupita", "admin", "sudoers")) }
// Or as other Iterables
val userList = yaml.as[List[User]]
val userSet = yaml.as[Set[User]]
// Even as Array
val userArray = yaml.as[Array[User]]
// Write Seq[User] to YamlSequence
val yamlUsers = Yaml.toYaml(users)
assert { yamlUsers(0).getInt("id") == 0 }
assert { yamlUsers(0).getString("name") == "root" }
assert { yamlUsers(0)("groups").as[Seq[String]] == Seq("root") }
assert { yamlUsers(1).getInt("id") == 1000 }
assert { yamlUsers(1).getString("name") == "lupita" }
assert { yamlUsers(1)("groups").as[Seq[String]] == Seq("lupita", "admin", "sudoers") }
```
### Extracting Values
You can traverse `YamlMapping` and `YamlSequence` to extract nested values. The `\`
extension method makes this clean and easy.
```scala
import scala.language.implicitConversions
import shampoo.yaml.{ *, given }
case class User(id: Int, name: String)
// Define how to construct User
given YamlConstructor[User] =
yaml => User(yaml("id"), yaml("name"))
val yaml = Yaml.load("""
node:
name: localhost
users:
- id: 0
name: root
- id: 1000
name: lupita
""")
// Get users array from node object
val users = (yaml \ "node" \ "users").as[Seq[User]]
// Get first user (at index 0) in users array
val user = (yaml \ "node" \ "users" \ 0).as[User]
// Get name of second user (at index 1) in users array
val name = (yaml \ "node" \ "users" \ 1 \ "name").as[String]
```
And, just as easy, you can do a recursive lookup with `\\` to collect values by
key.
```scala
// Get all "name" values
val names = (yaml \\ "name").map(_.as[String])
assert { names == Seq("localhost", "root", "lupita") }
```
## API Documentation
See [scaladoc](https://losizm.github.io/shampoo/latest/api/index.html)
for additional details.
## License
**Shampoo** is licensed under the Apache License, Version 2. See [LICENSE](LICENSE)
for more information.