Created
March 3, 2021 12:38
-
-
Save feoktant/0701fe9136f97d93a80e0d68fcad82bb to your computer and use it in GitHub Desktop.
Trying to achieve the same bson path as in KMongo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.feoktant.path | |
package domain | |
import scala.annotation.tailrec | |
object App extends App { | |
println(Sample.UserFields.emailAddress.id) | |
println(Sample.UserFields.emails(3).value) | |
} | |
case class EmailAddress( | |
id: String, | |
value: String, | |
) | |
case class User( | |
id: String, | |
name: String, | |
age: Int, | |
emailAddress: EmailAddress, | |
apples: List[String], | |
emails: List[EmailAddress], | |
) | |
object Sample { | |
trait Fields[T] { | |
def field(name: String): Field = new Field(name, None) | |
def field(name: String, parent: Field): Field = new Field(name, Some(parent)) | |
} | |
class Field( | |
private val name: String, | |
private val parent: Option[Field], | |
) { | |
lazy val dotNotation: String = { | |
@tailrec | |
def loop(p: Option[Field], acc: List[String]): String = p match { | |
case Some(par) => loop(par.parent, par.name :: acc) | |
case None => acc.mkString(".") | |
} | |
loop(parent, name :: Nil) | |
} | |
override def toString: String = dotNotation | |
} | |
object UserFields extends Fields[User] { | |
val id: Field = field("id") | |
val name: Field = field("name") | |
val age: Field = field("age") | |
val emailAddress: EmailEmbeddedDoc = new EmailEmbeddedDoc("emailAddress", None) | |
val apples: ArrayField = new ArrayField("apples") | |
val emails: EmailsArrayField = new EmailsArrayField("emails") | |
// if field only - field | |
class ArrayField( | |
private val name: String, | |
private val parent: Option[Field] = None, | |
) extends Field(name, parent) { self => | |
def apply(i: Int): Field = field(i.toString, self) | |
} | |
// if embedded document - ed | |
class EmailEmbeddedDoc( | |
private val name: String, | |
private val parent: Option[Field], | |
) extends Field(name, parent) { self => | |
val id: Field = field("id", self) | |
val value: Field = field("value", self) | |
} | |
class EmailsArrayField( | |
private val name: String, | |
private val parent: Option[Field] = None, | |
) extends EmailEmbeddedDoc(name, parent) { self => | |
def apply(i: Int): EmailEmbeddedDoc = new EmailEmbeddedDoc(i.toString, Some(self)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment