1use std::{fmt::Display, str::FromStr};
2
3mod client;
4mod keys;
5mod server;
6
7pub use client::{Client, ClientArgs};
8pub use server::{Server, ServerArgs};
9
10pub const GIT_IROH_ALPN: &[u8] = b"git/iroh/0";
12
13#[derive(Debug, Clone, Copy, PartialEq)]
16pub enum GitOp {
17 Push,
19 Fetch,
21}
22
23impl GitOp {
24 pub fn to_byte(self) -> u8 {
25 match self {
26 GitOp::Push => 1,
27 GitOp::Fetch => 2,
28 }
29 }
30
31 pub fn from_byte(b: u8) -> Option<Self> {
32 match b {
33 1 => Some(GitOp::Push),
34 2 => Some(GitOp::Fetch),
35 _ => None,
36 }
37 }
38}
39
40impl FromStr for GitOp {
41 type Err = anyhow::Error;
42
43 fn from_str(s: &str) -> Result<Self, Self::Err> {
44 Ok(match s {
45 "git-upload-pack" => GitOp::Push,
46 "git-receive-pack" => GitOp::Fetch,
47 _ => anyhow::bail!("unsupported command {s}"),
48 })
49 }
50}
51
52impl Display for GitOp {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 match self {
55 GitOp::Fetch => f.write_str("git-receive-pack"),
56 GitOp::Push => f.write_str("git-upload-pack"),
57 }
58 }
59}
60
61fn parse_iroh_url(url: &str) -> Result<iroh::PublicKey, anyhow::Error> {
63 let node_id_str = url.strip_prefix("iroh://").ok_or(anyhow::anyhow!(
64 "invalid iroh URL (expected iroh://): {}",
65 url
66 ))?;
67
68 Ok(node_id_str.parse::<iroh::PublicKey>()?)
69}