-
I'm looking to get a list of attribute names from a Schema to validate queries where we need to specify attributes as a String. I could define all valid attributes by hand, but since we already do that in the Schema definition, I thought that getting the attribute names should be possible. Looking into the encodeRecord function I see we can access the field names there, but I don't fully understand Could anyone provide some pointers to implement something similar to the following siganture?: def attributeNames[A](schema: Schema[A]): List[String] |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I'll give you a better answer later when I'm at my computer, I did do this at some point, it's possible but not super trivial. |
Beta Was this translation helpful? Give feedback.
-
@caenrique This is the start of a solution. It's in Scala 3 but written compatibly, in Scala 2 the only difference is how to install kind-projector: //> using lib "org.typelevel::toolkit::0.1.10"
//> using lib "org.systemfw::dynosaur-core::0.6.0"
//> using option -Ykind-projector
import dynosaur._
import cats._, data._, arrow._, free._, syntax.all._
import Schema.structure._
object Names {
def attributeNames[A](schema: Schema[A]): List[String] =
schema match {
case Record(record) =>
type Target[A] = List[String]
def extract[R](recordSchema: FreeApplicative[Field[R, *], R]): List[String] =
recordSchema
.analyze {
new FunctionK[Field[R, *], Target] {
def apply[B](field: Field[R, B]) =
field match {
case Field.Required(name, _, _) => List(name)
case Field.Optional(name, _, _) => List(name)
}
}
}
extract(record)
case _ => List.empty[String]
}
case class Foo(a: Int, b: Int)
val s = Schema.record[Foo] { field =>
(field("a", _.a), field("b", _.b)).mapN(Foo.apply)
}
val res = attributeNames(s)
// scala> Names.res
// val res0: List[String] = List(a, b)
} However note that it's only accessing the fields for a record (rather than an arbitrary schema), and only at one level of depth. If you want something more complete, you'd have to traverse the schema recursively. |
Beta Was this translation helpful? Give feedback.
@caenrique This is the start of a solution. It's in Scala 3 but written compatibly, in Scala 2 the only difference is how to install kind-projector: