Expand description
§🎠 Trotter
Trotter is an experimental crate that aims to make interacting with gemini servers fun and easy.
This crate comes with the trot
command-line program that exposes most of its
functionality. Install it with the command cargo install --features cli trotter
.
There’s also Fluffer, a crate for writing gemini server apps.
§😊 Requests
Trotter seeks to be a feature-complete gemini client library, while also being easy to use.
§Trot
If you’re only here to send a quick request, refer to the ergonomic trot
and
trot_in
methods.
#[tokio::main]
async fn main() {
trotter::trot("geminiprotocol.net") // gemini:// prefix and root slash can be elided
.await
.unwrap();
trotter::trot_in("localhost/input", "notice me!")
.await
.unwrap();
}
§Actors
For more-detailed requests, you can use an Actor
.
You can use the builder pattern to easily attach a user agent and client certificate to the actor.
Once you’ve built an Actor
, you can call Actor::get
to send a request
with it.
use trotter::{Actor, UserAgent};
#[tokio::main]
async fn main() {
let owo = Actor::default()
.user_agent(UserAgent::Indexer)
.cert_file("id/owo.crt")
.key_file("id/owo.key");
owo.get("localhost")
.await
.unwrap();
}
§🤖 User-agents
Did you know there’s a version of the robots.txt
standard for gemini?
(robots.txt for Gemini)
Trotter has robots functionality built-in. Once you set your user-agent, you
will receive a RobotDenied
error if you try to access a page you are
disallowed from.
I strongly suggest you do this if you’re using Trotter for a project that depends on other peoples’ content.
§🌕 Titan
Titan is a sister-protocol to gemini that allows clients to upload files. (read more)
To use titan, construct a Titan
object, and pass it to the Actor::upload
method.
use trotter::{Actor, Titan};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let g = Actor::default()
.upload(
"titan://localhost/",
Titan {
content: "Example content :DDDDDDDDDDDDDDDDDDDD".into(),
mimetype: "text/plain".into(),
token: None,
},
)
.await?
.gemtext()?;
println!("{g}");
Ok(())
}
§🎁 Responses
Once you receive a structured Response
, you can either weed through it
yourself, or rely on the helper functions it implements to preform common
operations.
§📖 Parsing
Trotter also provides tools for parsing gemtext.
use trotter::parse::Gemtext;
fn main() {
let txt = "# 💎
# Is
## So
> effing
* dope
man
=> /path/to/somewhere i can take u there
``` alt text goes here
Here's a table
| The | Best |
|-----|------|
| 😘 | 😪 |
```";
let gemtext = Gemtext::parse(txt);
println!("{gemtext:#?}");
}
§Tips
§Certificates
If you have access to a posix shell with openssl
installed, you can define the
following functions to easily generate and inspect x509 certificates.
certgen() { [ -f "${1:?usage: certgen [domain]}.key" ] || [ -f "$1.crt" ] || ( openssl req -new -subj "/CN=$1" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 3650 -nodes -out "$1.crt" -keyout "$1.key" && printf '📜 Cert generated\n' ) ;}
certinfo(){ openssl x509 -noout -text < "${1:?usage: certinfo [file]}" ;}
§Todo
For now, I want this to be a helpful tool for automating gemini requests. But ultimately, I would like for it to be robust enough to write a complete client with.
- Write response to file
- Get response as gemtext
- robots.txt support
- Custom errors
- Cli binary 👀
- Server certificates
- Tofu store directory
- Byte read/write timeout
Modules§
- Provides tools for parsing gemtext
Structs§
- Make a gemini request.
- A gemini response.
- Used for
Actor::upload
Enums§
- Enum for representing gemini status codes.
- Enum representing user-agents defined by the gemini version of the robots.txt spec.
Functions§
- 🎠 An ergonomic way to call
Actor::get
with the default actor. - 🎠 An ergonomic way to call
Actor::input
with the default actor.