Created
March 22, 2016 22:07
-
-
Save yusefnapora/a23ec9b990fe8ef0b1a7 to your computer and use it in GitHub Desktop.
Hashable marshalling
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
// The idea here is that case classes that extend `Hashable` will be converted to | |
// a Json AST using json4s, then written as canonical CBOR & hashed with SHA-256 | |
// | |
// The actual hashing happens in `MultiHash.forHashable`, which can fail if the | |
// Json conversion fails. | |
// | |
// I don't think this custom marshaller trick will work for signatures, though, | |
// because it needs the signing key as an input, which wouldn't be available to | |
// the gremlin-scala marshaller. | |
// | |
// but the marshaller is too "magical" anyway, and I think it's best avoided. | |
// | |
trait Hashable { | |
val excludedFields: List[String] = List("id") | |
def multiHash: Xor[ConversionToJsonFailed, MultiHash] = | |
MultiHash.forHashable(this) | |
} | |
object Hashable { | |
// Extend the default `Marshallable` implementation for `Hashable` case classes | |
// to include the computed `multiHash` as a vertex property. | |
// | |
// The default marshaller will only store the constructor parameters for a case class. | |
// Since the hash is a computed property, it doesn't get stored by default. | |
// This method creates a new `Marshallable` that will include the `multiHash` | |
def marshaller[CC <: Hashable with Product : Marshallable]: Marshallable[CC] = { | |
new Marshallable[CC] { | |
override def fromCC(cc: CC): FromCC = { | |
val defaultFromCC = implicitly[Marshallable[CC]].fromCC(cc) | |
val valueMap = cc.multiHash match { | |
case Xor.Right(multiHash) => | |
defaultFromCC.valueMap + | |
("multiHash" -> multiHash.base58) | |
case _ => | |
defaultFromCC.valueMap | |
} | |
FromCC(defaultFromCC.id, defaultFromCC.label, valueMap) | |
} | |
override def toCC(id: Id, valueMap: ValueMap): CC = | |
implicitly[Marshallable[CC]] | |
.toCC(id, valueMap + ("id" -> id)) | |
} | |
} | |
} | |
implicit val canonicalMarshaller = Hashable.marshaller[Canonical] | |
implicit val rawMetadataBlobMarshaller = Hashable.marshaller[RawMetadataBlob] | |
implicit val photoBlobMarshaller = Hashable.marshaller[PhotoBlob] | |
implicit val personMarshaller = Hashable.marshaller[Person] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment