glyde/rest/query

Query parameters, built so an absent one has no spelling. A Param can only be made here, so a rest.query call cannot be handed a hand-rolled pair that skipped the rules: these emit a parameter only when there is a value, and 0 is a value.

to_string is the other end of the same story: it is how a Param reaches the wire, so the whole answer to what a query looks like is in this module.

Also what a hand-rolled call needs, for an endpoint glyde does not wrap:

let call =
  rest.get(
    [seg.lit("guilds"), seg.guild(guild), seg.lit("audit-logs")],
    rest.Decoded(my_decoder),
  )
  |> rest.query(query.opt("limit", Some(50), query.number))

let submit = limiter.Submit(limiter.Ticket(1), rest.route(call))

Types

One key and one value, already encoded the way Discord reads it. Opaque so that every parameter on a call came through the constructors below.

pub opaque type Param

Values

pub fn comma(
  key: String,
  values: List(a),
  with encode: fn(a) -> String,
) -> List(Param)

An array parameter joined with commas, which Discord asks for on three parameters only, include_roles on GET /guilds/{id}/prune among them. An empty list emits nothing.

pub fn flag(value: Bool) -> String

Discord accepts True, true and 1. glyde always writes true.

pub fn number(value: Int) -> String
pub fn one(key: String, value: String) -> List(Param)

One parameter, always sent, for a flag whose value is the point.

pub fn opt(
  key: String,
  value: option.Option(a),
  with encode: fn(a) -> String,
) -> List(Param)

One parameter. None produces no pair at all.

pub fn repeat(
  key: String,
  values: List(a),
  with encode: fn(a) -> String,
) -> List(Param)

An array parameter as repeated keys, ?id=1&id=2, which is Discord’s documented default. An empty list emits nothing.

pub fn snowflake(value: id.Id(kind)) -> String
pub fn text(value: String) -> String

A value that is already the text Discord wants: a search term, an ISO-8601 timestamp. to_string does the percent-encoding.

pub fn to_string(params: List(Param)) -> option.Option(String)

The query string these parameters make, both halves percent-encoded, with no leading ?. None for an empty list, because a bare ? on the end of a URL is a common bug.

Search Document