Created
February 17, 2012 17:48
-
-
Save eparejatobes/1854586 to your computer and use it in GitHub Desktop.
neo4j fields and records with shapeless
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
import shapeless._ | |
import shapeless.TypeOperators._ | |
import shapeless.Record._ | |
import shapeless.BasisConstraint._ | |
import Neo4jTypesConstraints.OfNeo4jFieldsConstraint._ | |
import Neo4jTypesConstraints._ | |
import Neo4jTypes._ | |
object Neo4jTypes { | |
// set of valid value types for a neo4j field | |
type ValueTypes = Int :: Boolean :: String :: Byte :: Long :: Float :: | |
Array[String] :: Array[Byte] :: Array[Long] :: | |
HNil | |
// set of valid key types for a neo4j field | |
type KeyTypes = String | |
// field schemas; they're declared as objects extending this class | |
class Neo4jField[V](label: KeyTypes)(implicit ev: OfNeo4jValueTypes[V]) extends Field[V] {} | |
trait Neo4jRecordAux { | |
type Fields <: HList | |
} | |
// record schemas; they're declared as objects extending this class | |
class Neo4jRecord[L <: HList](val fields: L)(implicit ev: OfNeo4jFields[L]) extends Neo4jRecordAux { override type Fields = L } | |
} | |
object Neo4jTypesConstraints { | |
// a value of this type is evidence of L having all elements Neo4jFields | |
trait OfNeo4jFieldsConstraint[L <: HList] | |
object OfNeo4jFieldsConstraint { | |
// an empty list is ok | |
implicit def hnilOfNeo4jFields = new OfNeo4jFieldsConstraint[HNil] {} | |
// head should be a field | |
implicit def hlistOfNeo4jFields[H <: Neo4jField[_], T <: HList](implicit ct: OfNeo4jFieldsConstraint[T]) = | |
new OfNeo4jFieldsConstraint[H :: T] {} | |
// accepts an HList where every element is x: Neo4jField[X] | |
def ofNeo4jFields[L <: HList](l: L)(implicit ev: OfNeo4jFields[L]) = true | |
} | |
// // a value of this type is evidence of V contained in Neo4jTypes.ValueTypes | |
type OfNeo4jValueTypes[V] = BasisConstraint[V :: HNil, ValueTypes] | |
// value of this type is evidence of L being of neo4j field schemas | |
type OfNeo4jFields[L <: HList] = OfNeo4jFieldsConstraint[L] | |
} | |
object FieldsTest { | |
// sample fields | |
case object age extends Neo4jField[Int](label = "age") | |
case object name extends Neo4jField[String](label = "name") | |
case object id extends Neo4jField[Int](label = "id") | |
// wrong value type, doesn't compile | |
// case object wrongField extends Neo4jField[URL](label = "uh") | |
// wrong key type, doesn't compile | |
// object data extends Neo4jField[Byte](label = 32) | |
// value checks | |
val x: age.valueType = 132 | |
val anAgeEntry: FieldEntry[age.type] = (age -> 142) | |
// val nono: FieldEntry[age.type] = (age -> "uh") | |
} | |
object RecordsTest { | |
import FieldsTest._ | |
// sample records | |
case object userProps extends Neo4jRecord(id :: name :: age :: HNil) | |
case object idProps extends Neo4jRecord(id :: HNil) | |
// you need to pass in Neo4jFields | |
// case object wrongRecord extends Neo4jRecord(id :: "yeah" :: HNil) | |
} |
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
import shapeless._ | |
import shapeless.Record._ | |
// this doesn't work, don't know why | |
object RecordConstraints { | |
import Neo4jTypes._ | |
// witness of E being an entry of schema R | |
trait RecordConstraint[E <: HList, R <: HList] | |
type EntryOf[R <: HList] = { | |
type λ[E <: HList] = RecordConstraint[E, R] | |
} | |
// hnil is ok for every schema | |
implicit def hnilSchema[R <: HList] = new RecordConstraint[HNil, R] {} | |
// hcons | |
implicit def hlistSchema[F <: Neo4jField[_], V <: FieldEntry[F], T <: HList, R <: HList] | |
(implicit bct : RecordConstraint[T, R], | |
sel : Selector[R, F] | |
) = new RecordConstraint[ V :: T, R] {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment