2015-09-23 5 views
1

Я пытаюсь обернуть метод .getAs[T](String) в классе BSONDocument Reactive Mongo, чтобы я мог указать путь к свойству, а не просто по имени. Вот код, который я придумал:Реактивный Mongo не смог найти читателя при обертке .getAs()

def getPropertyFromBSONWithTransform[T1, T2](transform: T1 => T2, doc: BSONDocument, path: List[String]): Option[T2] = { 

def getPropertyFromBSON[T1](doc: Option[BSONDocument], path: List[String]): Option[T1] = doc match { 
    case None => None 
    case Some(d) => path match { 
    case List() => error("Shouldnt be here") 
    case s :: List() => d.getAs[T1](s) 
    case x :: xs => getPropertyFromBSON[T1](d.getAs[BSONDocument](x), xs) 
    } 
} 

val value = getPropertyFromBSON(Some(doc), path) 

value match { 
    case None => None 
    case Some(x) => Some(transform(x)) 
} 

}

Однако теперь он жалуется, не имея читателя. Точная ошибка:

Error:(26, 40) could not find implicit value for parameter reader: reactivemongo.bson.BSONReader[_ <: reactivemongo.bson.BSONValue, T1] 
    case s :: List() => d.getAs[T1](s) 
           ^

Я знаю, как решить эту проблему для одного типа, но я хочу, чтобы сохранить функцию общего, так что я не должен делать это для каждого типа мне нужно. Поскольку я хочу как можно больше отделить читателя от данных, я предпочитаю не создавать класс для его чтения.

ответ

0

Я думаю, вы забыли передать неявный читатель основному методу. Это должно быть работа.

def getPropertyFromBSONWithTransform[T1, T2](transform: T1 => T2, doc: BSONDocument, path: List[String])(implicit reader: BSONDocumentReader[T1]): Option[T2] = { 

    def getPropertyFromBSON(doc: Option[BSONDocument], path: List[String]): Option[T1] = doc match { 
    case None => None 
    case Some(d) => path match { 
     case List() => sys.error("Shouldnt be here") 
     case s :: List() => d.getAs[T1](s) 
     case x :: xs => getPropertyFromBSON(d.getAs[BSONDocument](x), xs) 
    } 
    } 

    getPropertyFromBSON(Some(doc), path).map(transform) 
}