title: Scalameta: Identify particular annotations
body: <p>I want to auto-generate REST API models in Scala using scalameta annotation macros. Specifically, given:</p>
  
  <pre><code>@Resource case class User(
  @get               id            : Int,
  @get @post @patch  name          : String,
  @get @post         email         : String,
                     registeredOn  : Long
  )
  </code></pre>
  
  <p>I want to generate:</p>
  
  <pre><code>object User {
    case class Get(id: Int, name: String, email: String)
    case class Post(name: String, email: String)
    case class Patch(name: Option[String])
  }
  
  trait UserRepo {
    def getAll: Seq[User.Get]
    def get(id: Int): User.Get
    def create(request: User.Post): User.Get
    def replace(id: Int, request: User.Put): User.Get
    def update(id: Int, request: User.Patch): User.Get
    def delete(id: Int): User.Get
  }
  </code></pre>
  
  <p>I have something working here: <a href="https://github.com/pathikrit/metarest" rel="nofollow noreferrer">https://github.com/pathikrit/metarest</a></p>
  
  <p>Specifically I am doing this:</p>
  
  <pre><code>import scala.collection.immutable.Seq
  import scala.collection.mutable
  import scala.annotation.{StaticAnnotation, compileTimeOnly}
  import scala.meta._
  
  class get extends StaticAnnotation
  class put extends StaticAnnotation
  class post extends StaticAnnotation
  class patch extends StaticAnnotation
  
  @compileTimeOnly("@metarest.Resource not expanded")
  class Resource extends StaticAnnotation {
    inline def apply(defn: Any): Any = meta {
      val (cls: Defn.Class, companion: Defn.Object) = defn match {
        case Term.Block(Seq(cls: Defn.Class, companion: Defn.Object)) =&gt; (cls, companion)
        case cls: Defn.Class =&gt; (cls, q"object ${Term.Name(cls.name.value)} {}")
        case _ =&gt; abort("@metarest.Resource must annotate a class")
      }
  
      val paramsWithAnnotation = for {
        Term.Param(mods, name, decltype, default) &lt;- cls.ctor.paramss.flatten
        seenMods = mutable.Set.empty[String]
        modifier &lt;- mods if seenMods.add(modifier.toString)
        (tpe, defArg) &lt;- modifier match {
          case mod"@get" | mod"@put" | mod"@post" =&gt; Some(decltype -&gt; default)
          case mod"@patch" =&gt;
            val optDeclType = decltype.collect({case tpe: Type =&gt; targ"Option[$tpe]"})
            val defaultArg = default match {
              case Some(term) =&gt; q"Some($term)"
              case None =&gt; q"None"
            }
            Some(optDeclType -&gt; Some(defaultArg))
          case _ =&gt; None
        }
      } yield modifier -&gt; Term.Param(Nil, name, tpe, defArg)
  
      val models = paramsWithAnnotation
        .groupBy(_._1.toString)
        .map({case (verb, pairs) =&gt;
          val className = Type.Name(verb.stripPrefix("@").capitalize)
          val classParams = pairs.map(_._2)
          q"case class $className[..${cls.tparams}] (..$classParams)"
        })
  
      val newCompanion = companion.copy(
        templ = companion.templ.copy(stats = Some(
          companion.templ.stats.getOrElse(Nil) ++ models
        ))
      )
  
      Term.Block(Seq(cls, newCompanion))
    }
  }
  </code></pre>
  
  <p>I am unhappy with the following snip of code:</p>
  
  <pre><code>   modifier match {
       case mod"@get" | mod"@put" | mod"@post" =&gt; ...
       case mod"@patch" =&gt; ...
       case _ =&gt; None
     }
  </code></pre>
  
  <p>The above code does "stringly" pattern matching on the annotations I have. Is there anyway to re-use the exact annotations I have to pattern match for these:</p>
  
  <pre><code>class get extends StaticAnnotation
  class put extends StaticAnnotation
  class post extends StaticAnnotation
  class patch extends StaticAnnotation
  </code></pre>