gopher-protocol 0.1.0

An implementation of the Gopher protocol (gopher://) and its Gopher+ successor: async client, RFC 1436 menu parser with RFC 4266 URLs, and Gopher+ attribute blocks, alternate views, and ASK forms. The parser half has no dependencies.
Documentation
# gopher-protocol

An implementation of [Gopher](https://datatracker.ietf.org/doc/html/rfc1436)
(`gopher://`, port 70) and its [Gopher+](https://github.com/gopher-protocol/gopher-plus)
successor in Rust: an async client, an RFC 1436 menu parser with RFC 4266 URL
synthesis, and the Gopher+ attribute, view, and form model.

This is not the reference implementation of Gopher, and it does not speak for
the protocol's community.

## Gopher+

Gopher+ (1993) is an upward-compatible superset, so it is not a separate
protocol here: a plain RFC 1436 menu just has no Gopher+ markers on its items.
What it adds is a response header carrying a real length, attribute blocks
(`+INFO`, `+ADMIN`, `+VIEWS`) that describe an item without fetching it,
alternate representations, and `+ASK` forms for interactive queries.

Gopher-II (the [later draft](https://datatracker.ietf.org/doc/html/draft-matavka-gopher-ii-02))
is not implemented.

## Two halves, separately usable

The parsers have no dependencies and are always compiled, Gopher+ included.
A consumer that only renders gophermaps takes the crate without the client and
pulls no async runtime:

```toml
gopher-protocol = { version = "0.1", default-features = false }
```

The client rides the default `client` feature.

## Example

```rust,no_run
# async fn run() -> Result<(), gopher_protocol::ClientError> {
let reply = gopher_protocol::fetch("gopher://gopher.floodgap.com/1/").await?;
for item in gopher_protocol::parse_menu(&String::from_utf8_lossy(&reply.body)) {
    println!("{:?} {}", item.kind, item.display);
}
# Ok(())
# }
```

## Scope

A client and a parser. It does not serve gopher, and it holds no document or
render model: how a `Search` or `Image` item should look is the consumer's
decision.

Gopher carries no status line and no MIME type, so `Response::mime` is a
best-effort inference from the item type, documented as a client convention
rather than part of the RFC.

## License

MIT.