#![doc = include_str!("../README.md")]
#[doc(hidden)]
#[macro_export]
macro_rules! flag_methods {
(
$(#[$attr:meta])*
$vis:vis fn $name:ident / $name_if:ident, $field:ident, $doc_if:literal
) => {
$(#[$attr])*
#[must_use]
$vis fn $name(self) -> Self {
self.$name_if(true)
}
#[doc = $doc_if]
#[must_use]
$vis fn $name_if(mut self, value: bool) -> Self {
self.$field = value;
self
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_repo_path {
($ty:ident) => {
impl<'a> $ty<'a> {
#[must_use]
pub fn repo_path(mut self, path: &'a std::path::Path) -> Self {
self.repo_path = Some(path);
self
}
}
impl<'a> $crate::RepoPath<'a> for $ty<'a> {
fn repo_path(self, path: &'a std::path::Path) -> Self {
self.repo_path(path)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! cow_str_newtype {
(
$(#[$attr:meta])*
$vis:vis struct $name:ident, $error:ident($inner:ty), $invalid:literal
) => {
$(#[$attr])*
#[derive(Clone, Debug, Eq, PartialEq, ::serde::Deserialize)]
#[serde(try_from = "String")]
$vis struct $name(::std::borrow::Cow<'static, str>);
#[doc = concat!("Error returned when parsing an invalid `", stringify!($name), "`.")]
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[error(transparent)]
$vis struct $error(pub $inner);
impl $name {
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
#[must_use]
pub const fn from_static_or_panic(input: &'static str) -> Self {
assert!(Self::validate(input).is_ok(), $invalid);
Self(::std::borrow::Cow::Borrowed(input))
}
}
impl ::std::fmt::Display for $name {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(formatter, "{}", self.0)
}
}
impl ::std::convert::AsRef<::std::ffi::OsStr> for $name {
fn as_ref(&self) -> &::std::ffi::OsStr {
self.as_str().as_ref()
}
}
impl ::std::str::FromStr for $name {
type Err = $error;
fn from_str(input: &str) -> ::std::result::Result<Self, Self::Err> {
Self::validate(input)?;
Ok(Self(::std::borrow::Cow::Owned(input.to_string())))
}
}
impl ::std::convert::TryFrom<String> for $name {
type Error = $error;
fn try_from(value: String) -> ::std::result::Result<Self, Self::Error> {
value.parse()
}
}
impl ::serde::Serialize for $name {
fn serialize<S: ::serde::Serializer>(
&self,
serializer: S,
) -> ::std::result::Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
};
}
pub mod add;
pub mod branch;
pub mod checkout;
pub mod clean;
pub mod clone;
pub mod commit;
pub mod commit_id;
pub mod commit_ish;
pub mod config;
pub mod diff;
pub mod fetch;
pub mod init;
pub mod ls_remote;
pub mod push;
pub mod ref_format;
pub mod remote;
pub mod repository;
pub mod reset;
pub mod rev_list;
pub mod rev_parse;
pub mod show;
pub mod show_ref;
pub mod status;
pub mod tag;
pub mod worktree;
use std::path::Path;
pub use cmd_proc::CommandError;
pub trait Porcelain: Sized {
fn porcelain_if(self, value: bool) -> Self;
fn porcelain(self) -> Self {
self.porcelain_if(true)
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_porcelain {
($ty:ident) => {
impl<'a> $ty<'a> {
#[must_use]
pub fn porcelain(self) -> Self {
self.porcelain_if(true)
}
#[must_use]
pub fn porcelain_if(mut self, value: bool) -> Self {
self.porcelain = value;
self
}
}
impl<'a> $crate::Porcelain for $ty<'a> {
fn porcelain_if(self, value: bool) -> Self {
self.porcelain_if(value)
}
}
};
}
#[must_use = "repo_path returns a modified builder; the return value must be used"]
pub trait RepoPath<'a>: Sized {
fn repo_path(self, path: &'a Path) -> Self;
}
pub trait Build {
fn build(self) -> cmd_proc::Command;
}
fn base_command(repo_path: Option<&Path>) -> cmd_proc::Command {
cmd_proc::Command::new("git").optional_option("-C", repo_path)
}