Skip to content

Repository files navigation

Germ

crates.io docs.rs github.com

Germ parses and generates Gemtext, converts it to HTML or Markdown, handles response metadata, and makes Gemini requests. Its default features include the request client and its network and TLS dependencies. Disable default features to use ast, convert, meta, or quick without normal dependencies.

Usage

[dependencies]
germ = "0.5.0"

To select features without the default request client:

[dependencies]
germ = { version = "0.5.0", default-features = false, features = ["ast"] }

Features

Feature Description
default ast, convert, meta, request
ast Construct AST trees from raw Gemtext
blocking Make blocking Gemini requests
convert Convert Gemtext to HTML or Markdown
request Make asynchronous Gemini requests
meta Parse and format Gemini response metadata
macros Generate AST and converted output with macros
quick Build individual Gemtext lines

Gemini requests verify server certificates against Mozilla CA roots by default. For a self-signed capsule, add its certificate in DER form to a rustls::RootCertStore, then pass that store to request::blocking::request_with_roots or request::non_blocking::request_with_roots. The store is a trust anchor, not an exact certificate fingerprint pin. Save and review the certificate separately before trusting it; the default request functions do not remember certificates between calls.

Requests time out after 30 seconds and have a 16 MiB response limit, including the header. To change these limits or the trusted roots, set the fields of request::RequestOptions and pass it to request::blocking::request_with_options or request::non_blocking::request_with_options. The blocking system DNS lookup may outlast the timeout before it returns.

For trust on first use, implement request::CertificateStore with durable storage keyed by hostname and port, then pass it to blocking::request_with_tofu or non_blocking::request_with_tofu alongside RequestOptions. These methods verify the presented certificate and complete the TLS handshake before saving a first-use certificate or checking an existing one, and before sending the URL. They reject an unexpected certificate change until the stored certificate expires. An expired certificate is replaced after the new one passes validation. The store must persist each update before returning; callers can remove a pin deliberately when changing trust early. Store methods run synchronously, including in the async request path. TOFU uses the timeout and response size limits from RequestOptions but ignores its root_certificates field.

Ast::to_gemtext() serialises parsed nodes and retains a consistent LF or CRLF style and a final line ending. Mixed line endings and optional spaces after Gemtext markers can be normalised, so exact source round trips are not guaranteed.

HTML conversion escapes Gemtext content. HTML and Markdown conversion emit links for relative targets and Gemini, Gopher, HTTP, HTTPS, mailto, and FTP URLs; other schemes are shown as text. Markdown conversion escapes literal text, link labels, and destinations, and chooses a code fence that does not close inside preformatted content.

Meta parses quoted MIME parameters and quotes values as needed when formatting them.

quick::link(url, label) takes the URL first and an optional label second.

Unknown Gemini status codes retain their numeric value. Use Status::category() to inspect the response category indicated by the first digit.

Examples

Runnable examples can be found within the examples/ directory.

Run one with just example ast_to_gemtext.

just diff fetches gemini://geminiprotocol.net/ with a process-local TOFU certificate store. The certificate pin is not retained between runs. The example reports source formatting changes and checks that serialising and reparsing preserves the parsed nodes.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

🦠 The Definitive Gemini Protocol Toolkit

Topics

Resources

Stars

11 stars

Watchers

1 watching

Forks

Sponsor this project

Used by

Contributors

Languages