Can lift-mongodb or lift-json handle Enumeration values?

627 views
Skip to first unread message

Barry Kaplan

unread,
Aug 25, 2010, 8:35:41 PM8/25/10
to Lift
I'm getting errors wrt $outer. Wondering if I'm missing something
simple.

Joni Freeman

unread,
Aug 26, 2010, 12:35:19 AM8/26/10
to Lift
Hi,

No support for Enumeration yet. Could you please open a ticket?

Meanwhile you might want to examine if a custom serializer can handle
Enumerations. See CustomClassExamples from
http://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/test/scala/net/liftweb/json/SerializationExamples.scala
. The example adds a serializer for Interval type.

Cheers Joni

Barry Kaplan

unread,
Aug 26, 2010, 7:32:37 PM8/26/10
to Lift
Yes, quite simple with custom serializer :


class EnumerationSerializer[E <: Enumeration: ClassManifest](enum: E)
extends json.Serializer[E#Value] {

import JsonDSL._
val EnumerationClass = classOf[E#Value]
val formats = Serialization.formats(NoTypeHints)

def deserialize(implicit format: Formats):
PartialFunction[(TypeInfo, JValue), E#Value] = {
case (TypeInfo(EnumerationClass, _), json) => json match {
case JString(value) => enum.withName(value)
case value => throw new MappingException("Can't convert " +
value + " to "+ EnumerationClass)
}
}

def serialize(implicit format: Formats): PartialFunction[Any,
JValue] = {
case i: E#Value => i.toString
}
}

tommycli

unread,
Sep 9, 2010, 1:38:11 AM9/9/10
to Lift
I think you should file a ticket for that code to be included in the
lift codebase. I think it'd be very useful.

Malcolm

unread,
Sep 10, 2010, 2:22:29 PM9/10/10
to Lift
I've tried to use this approach with a Enumeration like:

object GenderType extends scala.Enumeration {
type GenderType = Value
val Boys, Girls, Mens, Womens, Mixed, Other = Value
}

When I try to us the new serializer

implicit val formats = Serialization.formats(NoTypeHints) + new
EnumerationSerializer[GenderType]

I get this error

error: not found: type GenderType

I'm a bit stumped on this.

Thanks
Malcolm


But if I just use the type in other expressions it works fine.

Joni Freeman

unread,
Sep 12, 2010, 10:28:15 AM9/12/10
to Lift
Hi,

Shouldn't it be:

implicit val formats = Serialization.formats(NoTypeHints) + new
EnumerationSerializer(GenderType)

Cheers Joni

On 10 syys, 21:22, Malcolm <malsmith3...@gmail.com> wrote:
> I've tried to use this approach with a Enumeration like:
>
> object GenderType extends scala.Enumeration {
>         type GenderType = Value
>         val Boys, Girls, Mens, Womens, Mixed, Other = Value
>
> }
>
> When I try to us the new serializer
>
>  implicit val formats = Serialization.formats(NoTypeHints) + new
> EnumerationSerializer[GenderType]
>
> I get this error
>
> error: not found: type GenderType
>
> I'm a bit stumped on this.
>
> Thanks
> Malcolm
>
> But if I just use the type in other expressions it works fine.
>
> On Sep 9, 1:38 am, tommycli <tommy...@ucla.edu> wrote:
>
> > I think you should file a ticket for that code to be included in the
> > lift codebase. I think it'd be very useful.
>
> > On Aug 26, 5:32 pm, Barry Kaplan <meme...@gmail.com> wrote:
>
> > > Yes, quite simple with custom serializer :
>
> > > class EnumerationSerializer[E <:Enumeration: ClassManifest](enum: E)
> > > extendsjson.Serializer[E#Value] {

tommycli

unread,
Sep 19, 2010, 7:14:46 PM9/19/10
to Lift
An issue I'm having with this custom de/serializer is that the
deserialize function does not distinguish between Enumerations. The
partial function matches every Enumeration value as:

val EnumerationClass = class scala.Enumeration$Value

and the TypeInfo parameter is also class scala.Enumeration$Value.

Can't figure out how to get around this.

Ross Mellgren

unread,
Sep 19, 2010, 7:26:56 PM9/19/10
to lif...@googlegroups.com
If the serialization is based on reflection (runtime typing) then you're out of luck without some serious hoop-jumping. The type of an enumeration value is erased down to Enumeration#Value during compilation and the singleton that encloses it is lost unless you either have an enum instance and can manually reach into it's hidden $outer field, or use the Scala compiler's signature information to lift the SingleType.

-Ross

> --
> You received this message because you are subscribed to the Google Groups "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
>

tommycli

unread,
Sep 21, 2010, 12:24:18 AM9/21/10
to Lift
Here's the solution I ended up using:

object StarClass {
case class Value(name: String)
val Giant = Value("Giant")
val B = Value("B")
val A = Value("A")
val F = Value("F")
val G = Value("G")
val K = Value("K")
val M = Value("M")
val Compact = Value("Compact")
}

Upside is that you get the type safety of Enumerations if you never
use the constructor outside of the singleton definition. Downside is
that it makes your JSON serialization have an extra level complexity.

Ross also suggested:
"""
Yep, that's similar to the Java enum approach. You could also make
your class constructor private, if you wanted to seal it entirely:

object StarClass {
class Value private (val name: String)
val Giant = new Value("Giant")
val B = Value("B")
...
}

-Ross
"""


On Sep 19, 5:26 pm, Ross Mellgren <dri...@gmail.com> wrote:
> If the serialization is based on reflection (runtime typing) then you're out of luck without some serious hoop-jumping. The type of anenumerationvalue is erased down toEnumeration#Value during compilation and the singleton that encloses it is lost unless you either have an enum instance and can manually reach into it's hidden $outer field, or use the Scala compiler's signature information to lift the SingleType.
>
> -Ross
>
> On Sep 19, 2010, at 7:14 PM, tommycli wrote:
>
> > An issue I'm having with this custom de/serializer is that the
> > deserialize function does not distinguish between Enumerations. The
> > partial function matches everyEnumerationvalue as:
Reply all
Reply to author
Forward
0 new messages