{"id":31733291,"url":"https://github.com/losizm/shampoo","last_synced_at":"2026-04-17T09:32:25.306Z","repository":{"id":215031738,"uuid":"737874249","full_name":"losizm/shampoo","owner":"losizm","description":"The YAML library for Scala","archived":false,"fork":false,"pushed_at":"2025-04-05T09:50:12.000Z","size":3111,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T08:23:37.204Z","etag":null,"topics":["scala","yaml"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/losizm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-01T20:06:10.000Z","updated_at":"2025-04-03T06:12:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"958d094b-cbfd-4063-a9ce-55f8d4b454f8","html_url":"https://github.com/losizm/shampoo","commit_stats":null,"previous_names":["losizm/shampoo"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/losizm/shampoo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losizm%2Fshampoo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losizm%2Fshampoo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losizm%2Fshampoo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losizm%2Fshampoo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/losizm","download_url":"https://codeload.github.com/losizm/shampoo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losizm%2Fshampoo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31923141,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T09:10:15.403Z","status":"ssl_error","status_checked_at":"2026-04-17T09:10:14.455Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["scala","yaml"],"created_at":"2025-10-09T08:23:18.830Z","updated_at":"2026-04-17T09:32:25.300Z","avatar_url":"https://github.com/losizm.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shampoo\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.losizm/shampoo_3.svg?label=Maven%20Central)](https://central.sonatype.com/search?q=g:com.github.losizm%20a:shampoo_3)\n\nThe YAML library for Scala.\n\n## Getting Started\nTo get started, add **Shampoo** to your project:\n\n```scala\nlibraryDependencies += \"com.github.losizm\" %% \"shampoo\" % \"1.0.0\"\n```\n\nThe underlying YAML processor is provided by [SnakeYAML Engine](https://github.com/snakeyaml/snakeyaml-engine/),\nso it'll be added transitively.\n\n## Lather Up!\nReading and writing are powered by `YamlConstructor` and `YamlRepresenter`.\nLibrary-provided implementations are available for working with standard types,\nsuch as `String`, `Int`, etc. You must define custom implementations to work\nwith other types.\n\n```scala\nimport scala.language.implicitConversions\n\nimport shampoo.yaml.{ *, given }\n\ncase class User(id: Int, name: String, groups: Seq[String])\n\n// Define how to construct User from YAML\ngiven YamlConstructor[User] with\n  def construct(yaml: YamlNode) =\n    User(\n      yaml(\"id\"),\n      yaml(\"name\"),\n      yaml(\"groups\")\n    )\n\n// Load YAML mapping\nval yaml = Yaml.load(\"\"\"\n  id: 1000\n  name: lupita\n  groups:\n    - lupita\n    - admin\n    - sudoers\n\"\"\")\n\n// Construct and verify\nval user = yaml.as[User]\nassert(user.id == 1000)\nassert(user.name == \"lupita\")\nassert(user.groups == Seq(\"lupita\", \"admin\", \"sudoers\"))\n\n// Define how to represent YAML from User\ngiven YamlRepresenter[User] with\n def represent(user: User) =\n    Yaml.map(\n      \"id\"     -\u003e user.id,\n      \"name\"   -\u003e user.name,\n      \"groups\" -\u003e user.groups\n    )\n\n// Represent and verify\nval yamlUser = Yaml.toYaml(user)\nassert(yamlUser.getInt(\"id\") == 1000)\nassert(yamlUser.getString(\"name\") == \"lupita\")\nassert(yamlUser(\"groups\").as[Seq[String]] == Seq(\"lupita\", \"admin\", \"sudoers\"))\n```\n\nSpecial implementations are available for working with collections. For example,\nif `YamlConstructor[User]` is defined, `YamlConstructor[Seq[User]]` can be\ninferred. The same applies to `YamlRepresenter[User]` and `YamlRepresenter[Seq[User]]`.\n\n```scala\n// Load YAML sequence\nval yaml = Yaml.load(\"\"\"\n  - id: 0\n    name: root\n    groups:\n      - root\n  - id: 1000\n    name: lupita\n    groups:\n      - lupita\n      - admin\n      - sudoers\n\"\"\")\n\n// Read YamlSequence as Seq[User]\nval users = yaml.as[Seq[User]]\nassert { users(0) == User(0, \"root\", Seq(\"root\")) }\nassert { users(1) == User(1000, \"lupita\", Seq(\"lupita\", \"admin\", \"sudoers\")) }\n\n// Or as other Iterables\nval userList = yaml.as[List[User]]\nval userSet  = yaml.as[Set[User]]\n\n// Even as Array\nval userArray = yaml.as[Array[User]]\n\n// Write Seq[User] to YamlSequence\nval yamlUsers = Yaml.toYaml(users)\nassert { yamlUsers(0).getInt(\"id\") == 0 }\nassert { yamlUsers(0).getString(\"name\") == \"root\" }\nassert { yamlUsers(0)(\"groups\").as[Seq[String]] == Seq(\"root\") }\nassert { yamlUsers(1).getInt(\"id\") == 1000 }\nassert { yamlUsers(1).getString(\"name\") == \"lupita\" }\nassert { yamlUsers(1)(\"groups\").as[Seq[String]] == Seq(\"lupita\", \"admin\", \"sudoers\") }\n```\n\n### Extracting Values\nYou can traverse `YamlMapping` and `YamlSequence` to extract nested values. The `\\`\nextension method makes this clean and easy.\n\n```scala\nimport scala.language.implicitConversions\n\nimport shampoo.yaml.{ *, given }\n\ncase class User(id: Int, name: String)\n\n// Define how to construct User\ngiven YamlConstructor[User] =\n  yaml =\u003e User(yaml(\"id\"), yaml(\"name\"))\n\nval yaml = Yaml.load(\"\"\"\n  node:\n    name: localhost\n    users:\n      - id: 0\n        name: root\n      - id: 1000\n        name: lupita\n\"\"\")\n\n// Get users array from node object\nval users = (yaml \\ \"node\" \\ \"users\").as[Seq[User]]\n\n// Get first user (at index 0) in users array\nval user = (yaml \\ \"node\" \\ \"users\" \\ 0).as[User]\n\n// Get name of second user (at index 1) in users array\nval name = (yaml \\ \"node\" \\ \"users\" \\ 1 \\ \"name\").as[String]\n```\n\nAnd, just as easy, you can do a recursive lookup with `\\\\` to collect values by\nkey.\n\n```scala\n// Get all \"name\" values\nval names = (yaml \\\\ \"name\").map(_.as[String])\nassert { names == Seq(\"localhost\", \"root\", \"lupita\") }\n```\n\n\n## API Documentation\nSee [scaladoc](https://losizm.github.io/shampoo/latest/api/index.html)\nfor additional details.\n\n## License\n**Shampoo** is licensed under the Apache License, Version 2. See [LICENSE](LICENSE)\nfor more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosizm%2Fshampoo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flosizm%2Fshampoo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosizm%2Fshampoo/lists"}