1pub mod accept_maintainership;
2pub mod agent_guidance;
3pub mod apk;
4pub mod blossom;
5mod cache;
6pub mod ci;
7pub mod cli_interactor;
8pub mod client;
9pub mod container_manifest;
10pub mod content_tags;
11pub mod event_ordering;
12pub mod fetch;
13pub mod git;
14pub mod git_events;
15pub mod git_http_auth;
16pub mod list;
17pub mod login;
18pub mod mbox_parser;
19pub mod nip_ad;
20pub mod nsite;
21pub mod oci;
22pub mod output_mode;
23pub mod proposal_base;
24pub mod push;
25pub mod relay_auth;
26pub mod relay_information;
27pub mod release_download;
28pub mod release_manifest;
29pub mod repo_ref;
30pub mod repo_state;
31pub mod self_update;
32pub mod signer;
33pub mod software_release;
34pub mod tls;
35pub mod utils;
36pub mod version_check;
37
38use anyhow::{Result, anyhow};
39use directories::ProjectDirs;
40use nostr::prelude::Url;
41pub use signer::NgitSigner;
42
43pub fn get_dirs() -> Result<ProjectDirs> {
44 ProjectDirs::from("", "", "ngit").ok_or(anyhow!(
45 "should find operating system home directories with rust-directories crate"
46 ))
47}
48
49pub trait UrlWithoutSlash {
50 fn as_str_without_trailing_slash(&self) -> &str;
51 fn to_string_without_trailing_slash(&self) -> String;
52}
53
54impl UrlWithoutSlash for Url {
55 fn as_str_without_trailing_slash(&self) -> &str {
56 let url_str = self.as_str();
57 if let Some(without) = url_str.strip_suffix('/') {
58 without
59 } else {
60 url_str
61 }
62 }
63
64 fn to_string_without_trailing_slash(&self) -> String {
65 self.as_str_without_trailing_slash().to_string()
66 }
67}