Saturday, August 25, 2012

Kiama & macro

Here is a quick and dirty example of using kiama along with the fields macro.
import annotated.{ Field => AnnField, Fields => AnnFields }

object pp {
    private object kpp extends org.kiama.output.PrettyPrinter
    import kpp._

    private def anyToDoc(any : Any) : Doc =
        any match {
            case song : Song        => annotatedToDoc("Song", song, songFields)
            case artist : Artist    => annotatedToDoc("Artist", artist, artistFields)
            case comp : Compilation => annotatedToDoc("Compilation", comp, compilationFields)
            case job : UploaderJob  => annotatedToDoc("Job", job, uploaderJobFields)

            case map : Map[_, _] =>
                list(map.iterator.toList,
                    prefix = "Map",
                    elemToDoc = {
                        (pair : (Any, Any)) =>
                            anyToDoc(pair._1) <> " -> " <> nest(anyToDoc(pair._2))
                    })

            case seq : Seq[_] =>
                list(seq.toList, prefix = "Sequence", elemToDoc = anyToDoc)

            case _ => value(any)
        }

    private def annotatedToDoc[T <: AnyRef](name : String, t : T, fields : AnnFields[T, FieldArgs]) : Doc = {
        list(fields,
            prefix = name,
            elemToDoc = {
                (f : AnnField[T, FieldArgs]) =>
                    f.name <> " = " <> anyToDoc(f.get(t))
            })
    }

    def apply(any : Any) : String = pretty(anyToDoc(any))
}
pp (uploaderJob) easily prints data like this:
Job(
    artistMap = Map(
        KeyRef(1x) -> Artist(
                handle = Tester2,
                marks = Set(),
                id = None,
                name = None,
                website = None,
                country = None,
                location = None),
        KeyRef(2u) -> Artist(
                handle = Tester,
                marks = Set(),
                id = None,
                name = None,
                website = None,
                country = None,
                location = None)),
    songMap = Map(
        KeyRef(6t) -> Song(
                relativePath = Path(test7.mp3),
                title = test7,
                artistRefs = Set(KeyRef(2u)),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = Some(1999)),
        KeyRef(5c) -> Song(
                relativePath = Path(test6.mp3),
                title = test6,
                artistRefs = Set(KeyRef(2u)),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = Some(1999)),
        KeyRef(9i) -> Song(
                relativePath = Path(test3.mp3),
                title = test3,
                artistRefs = Set(KeyRef(1x)),
                tags = Set(),
                id = None,
                sourceId = Some(4),
                mixSongId = None,
                year = None),
        KeyRef(3w) -> Song(
                relativePath = Path(test5.mp3),
                title = test5,
                artistRefs = Set(KeyRef(2u)),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = Some(1999)),
        KeyRef(7l) -> Song(
                relativePath = Path(test.mp3),
                title = test,
                artistRefs = Set(),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = None),
        KeyRef(8f) -> Song(
                relativePath = Path(test2.mp3),
                title = test2,
                artistRefs = Set(),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = None),
        KeyRef(4p) -> Song(
                relativePath = Path(test4.mp3),
                title = test4,
                artistRefs = Set(KeyRef(2u)),
                tags = Set(),
                id = None,
                sourceId = None,
                mixSongId = None,
                year = Some(1999)),
    compilationMap = Map(
        KeyRef(11x) -> Compilation(
                title = Compo,
                songRefs = Sequence(KeyRef(6t)),
                marks = Set(),
                year = Some(1999),
                cdOrSide = Some(B)),
        KeyRef(10g) -> Compilation(
                title = Compo,
                songRefs = Sequence(KeyRef(3w), KeyRef(4p), KeyRef(5c)),
                marks = Set(),
                year = Some(1999),
                cdOrSide = Some(A))))

No comments:

Post a Comment