Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-3553

Codec for Scala Enumeration

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Open
    • Priority: Major - P3
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: API, Scala
    • Labels:
      None
    • Environment:
      Linux based environment

      Description

      Hi Folks,

      I've tried to use Scala Enumeration class in a case class that is a model stored in mongo using Scala Mongo Driver 2.4.2.

      I did not find any default Codec for it in my search so I tried to create a Codec for it based on this ticket SCALA-343.

      As the get method of CodecProvider only the clazz[T] value with Enumaration#Val or Enumeration#Value, is not possible to identify which Enumeration class should be decodec.

      Let me provide an example of an workaround I did for it:

      case object EnumOne extends Enumeration {
        val e1, e2 = Value
      }
       
      case object EnumTwo extends Enumeration {
        val e3, e4 = Value
      }
       
      object EnumerationCodecProvider extends CodecProvider {
        def isEnumVal[T](clazz: Class[T]): Boolean = {
         // I had to check the class name to know if it is a Enumeration Val or Value, since the   Enumeration#Val class is private 
          clazz.getName.equals("scala.Enumeration$Val") ||
            clazz.getName.equals("scala.Enumeration$Value")
        }
       
        override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] = {
          if (isEnumVal(clazz)) {
            EnumerationCodec.asInstanceOf[Codec[T]]
          } else {
            null
          }
        }
       
        object EnumerationCodec extends Codec[Enumeration#Value] {
          private val enumMap: Map[String, String => Enumeration#Value] = Map(
            "enum_one" -> EnumOne,
            "enum_two" -> EnumTwo
          )
       
          override def decode(reader: BsonReader, decoderContext: DecoderContext): Enumeration#Value = {
            val identifier = reader.getCurrentName
       
            val enumValue = reader.readString()
            // I used the enumMap indexed with the collection key (identifier) to get the Enumeration class
            enumMap(identifier).withName(enumValue)
            }
          }
       
          override def encode(writer: BsonWriter, value: Enumeration#Value, encoderContext: EncoderContext): Unit = {
            writer.writeString(value.toString)
          }
       
          override def getEncoderClass: Class[Enumeration#Value] = classOf[Enumeration#Value]
        }
      }
      

      Is there a plan to add it in a future release for Scala Enumeration class? Or any way to not use the enumMap strategie I used in the previous example?

      Thanks in advance,

        Attachments

          Activity

            People

            Assignee:
            ross.lawley Ross Lawley
            Reporter:
            ronierison.silva@gmail.com JOSE RONIERISON SANTOS SILVA
            Participants:
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated: