finger_protocol/lib.rs
1//! # finger-protocol
2//!
3//! Finger ([RFC 1288](https://datatracker.ietf.org/doc/html/rfc1288), port 79)
4//! and its successor WebFinger
5//! ([RFC 7033](https://www.rfc-editor.org/rfc/rfc7033.html)), which honours it
6//! by name.
7//!
8//! Both answer the same question, thirty years apart: *who is this person?*
9//! Finger answers with whatever text the host felt like printing. WebFinger
10//! answers with a JSON Resource Descriptor, which is why it, and not finger,
11//! is what resolves `@alice@example.social` on the fediverse.
12//!
13//! ## Two protocols, two features
14//!
15//! | | Module | Feature | Pulls |
16//! |---|---|---|---|
17//! | Finger, RFC 1288 | [`client`] | `client` | tokio, url |
18//! | WebFinger, RFC 7033 | [`webfinger`] | `webfinger` | serde, serde_json, percent-encoding |
19//!
20//! Both are on by default. Take `default-features = false` with just one when
21//! the other is dead weight.
22//!
23//! ## WebFinger without an HTTP client
24//!
25//! WebFinger rides on HTTPS and this crate deliberately contains no HTTP
26//! stack: it builds the request URL and parses the response, and the GET
27//! itself belongs to the caller, who already has an HTTP client and opinions
28//! about timeouts, redirects, and TLS. See [`webfinger`].
29//!
30//! Fingering a host is [`client::fetch`], documented on that module so the
31//! example stays honest when the `client` feature is off.
32
33#![forbid(unsafe_code)]
34
35#[cfg(feature = "client")]
36pub mod client;
37
38#[cfg(feature = "webfinger")]
39pub mod webfinger;
40
41#[cfg(feature = "client")]
42pub use client::{ClientError, DEFAULT_PORT, Query, Response, fetch, query};
43
44#[cfg(feature = "webfinger")]
45pub use webfinger::{Jrd, Link, MEDIA_TYPE, acct, request_url};