# Extracting type metadata from Elm code?

**URL:** <https://discourse.elm-lang.org/t/extracting-type-metadata-from-elm-code/6251>\
**Category:** Learn\
**Created:** [September 4, 2020, 11:58pm UTC](https://discourse.elm-lang.org/t/extracting-type-metadata-from-elm-code/6251 "2020-09-04T23:58:52Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![rkb](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rkb/32/672_2.png) [@rkb](https://discourse.elm-lang.org/u/rkb)\
**Post date:** [September 4, 2020, 11:58pm UTC](https://discourse.elm-lang.org/t/extracting-type-metadata-from-elm-code/6251/1 "2020-09-04T23:58:53Z")

</div>

The problem: Given a big, hairy, often-changing `Route` custom type, and a pair of functions `Route -> String` and `String -> Maybe Route`, how can we be sure that (almost) every Route turned into a string and back into Route produces the same value that we started with?

* * *

`Route` looks like:

```elm
module Route exposing (..)

import UserRoutes exposing UserRoutes
import TaskRoutes exposing TaskRoutes

type Route
    = Home
    | Settings
    | About
    | User String UserRoutes
    | Task Int TaskRoutes
    -- ...dozens more...

```

Is there some tool I can point at Route.elm, say “give me the structure of the `Route` type”, and have it follow the module imports, so that it returns an enumerable list of properties? Something like:

```auto
{
  type: "CustomType",
  name: "Route",
  members: [
    {
      name: "Home",
    },
    {
      name: "Settings",
    },
    {
      name: "About",
    },
    {
      name: "User",
      args: [
        {
          type: "String",
        },
        {
          type: "CustomType",
          name: "UserRoutes",
          members: [
            {
              name: "Summary",
            },
            {
              name: "Activity",
            },
            // ... etc ...
          ],
        }
      ],
    },
    {
      name: "Task",
      args: [
        {
          type: "Int",
        },
        {
          type: "CustomType",
          name: "TaskRoutes",
          members: [
            {
              name: "Active",
            },
            {
              name: "Overdue",
            },
            // ... etc ...
          ],
        }
      ],
    },
    // ... etc ...
  ]
}

```

I’m thinking that I’d use that to generate a RouteTest.elm file that uses default (or fuzzed) values for the Ints and Strings, which might look like:

```elm
suite : Test
suite =
    describe "routes"
        [ test "should parse generated cases" <|
            \_ ->
                let
                    data =
                        [ Home
                        , Settings
                        , About
                        , User "a" UserRoutes.Summary
                        , User "a" UserRoutes.Activity
                        , Task 1 TaskRoutes.Active
                        , Task 1 TaskRoutes.Overdue
                        -- ... plus the rest ...
                        ]

                    actual =
                        data |> List.map (routeToString >> routeFromString)

                    expected =
                        data |> List.map Just
                in
                actual |> Expect.equalLists expected
        ]

```

---

_[View the full topic](https://discourse.elm-lang.org/t/extracting-type-metadata-from-elm-code/6251)._
