{"id":24736729,"url":"https://github.com/hypertino/binders","last_synced_at":"2025-03-22T17:28:02.761Z","repository":{"id":57725062,"uuid":"67368306","full_name":"hypertino/binders","owner":"hypertino","description":"binders is a Scala/Scala.js library for creating serialization/mapping libraries and frameworks.","archived":false,"fork":false,"pushed_at":"2020-01-15T10:32:10.000Z","size":186,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-27T21:59:24.132Z","etag":null,"topics":["macro","scala","scalajs","serialization-engine"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hypertino.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}},"created_at":"2016-09-04T21:06:07.000Z","updated_at":"2020-01-15T10:32:12.000Z","dependencies_parsed_at":"2022-09-08T04:10:22.144Z","dependency_job_id":null,"html_url":"https://github.com/hypertino/binders","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypertino%2Fbinders","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypertino%2Fbinders/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypertino%2Fbinders/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypertino%2Fbinders/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hypertino","download_url":"https://codeload.github.com/hypertino/binders/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244993894,"owners_count":20544074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["macro","scala","scalajs","serialization-engine"],"created_at":"2025-01-27T21:59:26.436Z","updated_at":"2025-03-22T17:28:02.733Z","avatar_url":"https://github.com/hypertino.png","language":"Scala","readme":"[![Build Status](https://travis-ci.org/hypertino/binders.svg)](https://travis-ci.org/hypertino/binders)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hypertino/binders_2.13/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hypertino/binders_2.13)\n\n[ Latest releases and snapshots](https://oss.sonatype.org/#nexus-search;gav~com.hypertino~binders_*~~~)\n\n# About\n\n_binders_ is a Scala/Scala.js library for creating serialization/mapping libraries and frameworks. \n\nThe aim of _binders_ \nis to allow easily make fast (compile-time/macro based) serialization library for case-classes, collections, primitives. \nIt takes out most of the complexity dealing with macro.\n\nAnother thing provided by _binders_ is a schema-less (untyped) data represented by `Value` type.\n\nExisting examples of serialization libraries based on binders are:\n- [json-binders](https://github.com/hypertino/json-binders) very fast and flexible JSON serializer for Scala/Scala.js\n- [typesafe-config-binders](https://github.com/hypertino/typesafe-config-binders) easily read typesafe config directly to case classes \n- [cassandra-binders](https://github.com/hypertino/cassandra-binders) case/class mapping for cassandra to minimize boilerplate code\n\n# Usage\n\n## Serialization\n\nImplement trait `Serializer[C]` and provide methods with names starting `write` and accepts single argument with data \ntype that is serialized. Also, to serialize classes serializer should provide a method `getFieldSerializer`\n\n```scala\nimport com.hypertino.binders.core.Serializer\nimport com.hypertino.inflector.naming._\n\nclass MySerializer[C \u003c: Converter] extends Serializer[C] {\n  def writeInt(i: Int) = println(i)\n  def writeString(s: String) = println(s)\n  def writeNull = println(\"null\")\n\n  def getFieldSerializer(fieldName: String): Option[MySerializer[C]] = {\n    println(\"serializing:\" + fieldName)\n    Some(new MySerializer[C])\n  }\n}\n```\nThat's all. With this code you may \"serialize\" case-classes, collections, primitive types (int and string in this case).\n\n```scala\nval serializer = new MySerializer[PlainConverter.type]\nserializer.bind(A(10, \"hello\", None))  // case class\nserializer.bind(10) //primitive \nserializer.bind(Seq(1,2,3)) // collection\n```\n\nYou may also want to implement methods `beginObject`/`endObject` and `beginArray`/`endArray`. _binders_ will call these \nmethods according to the type provided to call `bind`\n\n\u003e `PlainConverter.type` is a converter of field-names that do nothing. There are more useful converters like `SnakeCaseToCamelCaseConverter`,\n`DashCaseToCamelCaseConverter`. They are used to transform field names according to the naming style we need.  \n\nMore detailed example of serializer in json-binders is [JSON serialiser](https://github.com/hypertino/json-binders/blob/master/jsonBinders/shared/src/main/scala/com/hypertino/binders/json/JsonSerializer.scala) \n\n## Deserialization\n\nImplement trait `Deserializer[C]` and provide methods for reading primitives and other data-types. Example:\n\n```scala\nimport com.hypertino.binders.core.Deserializer\nimport com.hypertino.inflector.naming._\nclass MyDeserializer[C \u003c: Converter](val fieldName: Option[String] = None) extends Deserializer[C] {\n  def readInt(): Int = 10\n  def readString(): String = \"hello\"\n  def isNull: Boolean = false\n\n  def iterator(): Iterator[MyDeserializer[C]] = Seq(\"x\",\"y\",\"z\").map(s =\u003e new MyDeserializer[C](Some(s))).toIterator\n}\n```\n\n\"deserializer\" usage example:\n\n```scala\nval deserializer = new MyDeserializer[PlainConverter.type]\nval a = deserializer.unbind[A] // = A(10,\"Hello\",Some(10))\nval i = deserializer.unbind[Int] // = 10\nval s = deserializer.unbind[String] // = \"hello\"\n```\n\nFull example of [JSON deserializer](https://github.com/hypertino/json-binders/blob/master/jsonBinders/shared/src/main/scala/com/hypertino/binders/json/JsonDeserializer.scala)\n\n## Value type\n\nYou may use `Value` type for runtime manipulation or for the schema-less data, when it's know known at a compile time\nexact type structure. `Value` type can be mixed into the typed structure if data is partially untyped. One of the\nexamples of this is extra properties when some class have attached additional, runtime-defined properties.  \n\n`Value` type is a sealed trait that can only be one of the following types:\n\n- `Obj` - an object/map structure\n- `Lst` - list/array/sequence\n- `Text` - string type\n- `Number` - numbers internally represented as BigDecimal\n- `Bool` - logical type\n- `Null` - null object/value\n\nSome examples:\n\n```scala\n// construct some Obj\nval obj = Obj.from(\"a\" -\u003e Obj.from(\"x\" → 1, \"y\" → \"yey\"))\n\n// if we have case-class we can convert it to Obj:\ncase class A(x: Int, y: String)  \n...\nval obj = A(10, \"hello\").toValue // equals to Obj.from(\"x\" -\u003e 10, \"y\" -\u003e \"hello)\n\n// we also can convert it back to case-class\nval a = obj.to[A]\n\n// case class with static fields (x) and extra/dynamic fields at the same level\ncase class B(x: Int, extra: Obj) extends WithExtra \nval b = obj.to[B]\nval obj2 = b.toValue // equals to Obj.from(\"x\" -\u003e 10, \"y\" -\u003e \"hello)\n\n```\n\n\u003e `Value.dynamic` method is implemented using scala `Dynamic` type, so you can access fields by name even they \n\u003e are not defined at compile-time \n\u003e \n\u003e ```scala\n\u003e val obj = Obj.from(\"a\" -\u003e Obj.from(\"x\" → 1, \"y\" → \"yey\"))\n\u003e val a = obj.dynamic.a // = Text(\"a\")\n\u003e ```\n\n\nYou may also find an example of mixing `Value` in a case-class [with json-binders](https://github.com/hypertino/json-binders#schemalesscustom-fields)\n\n# Download\n\n```sbt\nlibraryDependencies += \"com.hypertino\" %% \"binders\" % \"1.3.0\"\n```\nReleases published to Maven Central for Scala 2.11 - 2.13 JVM \u0026 JS (user `%%%` for Scala.js enabled projects)\n\nSnapshots live in Sonatype repository, include it additionally:\n```sbt\nresolvers ++= Seq(\n  Resolver.sonatypeRepo(\"public\")\n)\n```\n\n# License\n\n_binders_ library is available under the BSD 3-Clause License\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypertino%2Fbinders","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhypertino%2Fbinders","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypertino%2Fbinders/lists"}