summaryrefslogtreecommitdiffstats
path: root/vendor/git2/src/email.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/git2/src/email.rs')
-rw-r--r--vendor/git2/src/email.rs183
1 files changed, 183 insertions, 0 deletions
diff --git a/vendor/git2/src/email.rs b/vendor/git2/src/email.rs
new file mode 100644
index 000000000..d3ebc0384
--- /dev/null
+++ b/vendor/git2/src/email.rs
@@ -0,0 +1,183 @@
+use std::ffi::CString;
+use std::{mem, ptr};
+
+use crate::util::Binding;
+use crate::{raw, Buf, Commit, DiffFindOptions, DiffOptions, Error, IntoCString};
+use crate::{Diff, Oid, Signature};
+
+/// A structure to represent patch in mbox format for sending via email
+pub struct Email {
+ buf: Buf,
+}
+
+/// Options for controlling the formatting of the generated e-mail.
+pub struct EmailCreateOptions {
+ diff_options: DiffOptions,
+ diff_find_options: DiffFindOptions,
+ subject_prefix: Option<CString>,
+ raw: raw::git_email_create_options,
+}
+
+impl Default for EmailCreateOptions {
+ fn default() -> Self {
+ // Defaults options created in corresponding to `GIT_EMAIL_CREATE_OPTIONS_INIT`
+ let default_options = raw::git_email_create_options {
+ version: raw::GIT_EMAIL_CREATE_OPTIONS_VERSION,
+ flags: raw::GIT_EMAIL_CREATE_DEFAULT as u32,
+ diff_opts: unsafe { mem::zeroed() },
+ diff_find_opts: unsafe { mem::zeroed() },
+ subject_prefix: ptr::null(),
+ start_number: 1,
+ reroll_number: 0,
+ };
+ let mut diff_options = DiffOptions::new();
+ diff_options.show_binary(true).context_lines(3);
+ Self {
+ diff_options,
+ diff_find_options: DiffFindOptions::new(),
+ subject_prefix: None,
+ raw: default_options,
+ }
+ }
+}
+
+impl EmailCreateOptions {
+ /// Creates a new set of email create options
+ ///
+ /// By default, options include rename detection and binary
+ /// diffs to match `git format-patch`.
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ fn flag(&mut self, opt: raw::git_email_create_flags_t, val: bool) -> &mut Self {
+ let opt = opt as u32;
+ if val {
+ self.raw.flags |= opt;
+ } else {
+ self.raw.flags &= !opt;
+ }
+ self
+ }
+
+ /// Flag indicating whether patch numbers are included in the subject prefix.
+ pub fn omit_numbers(&mut self, omit: bool) -> &mut Self {
+ self.flag(raw::GIT_EMAIL_CREATE_OMIT_NUMBERS, omit)
+ }
+
+ /// Flag indicating whether numbers included in the subject prefix even when
+ /// the patch is for a single commit (1/1).
+ pub fn always_number(&mut self, always: bool) -> &mut Self {
+ self.flag(raw::GIT_EMAIL_CREATE_ALWAYS_NUMBER, always)
+ }
+
+ /// Flag indicating whether rename or similarity detection are ignored.
+ pub fn ignore_renames(&mut self, ignore: bool) -> &mut Self {
+ self.flag(raw::GIT_EMAIL_CREATE_NO_RENAMES, ignore)
+ }
+
+ /// Get mutable access to `DiffOptions` that are used for creating diffs.
+ pub fn diff_options(&mut self) -> &mut DiffOptions {
+ &mut self.diff_options
+ }
+
+ /// Get mutable access to `DiffFindOptions` that are used for finding
+ /// similarities within diffs.
+ pub fn diff_find_options(&mut self) -> &mut DiffFindOptions {
+ &mut self.diff_find_options
+ }
+
+ /// Set the subject prefix
+ ///
+ /// The default value for this is "PATCH". If set to an empty string ("")
+ /// then only the patch numbers will be shown in the prefix.
+ /// If the subject_prefix is empty and patch numbers are not being shown,
+ /// the prefix will be omitted entirely.
+ pub fn subject_prefix<T: IntoCString>(&mut self, t: T) -> &mut Self {
+ self.subject_prefix = Some(t.into_c_string().unwrap());
+ self
+ }
+
+ /// Set the starting patch number; this cannot be 0.
+ ///
+ /// The default value for this is 1.
+ pub fn start_number(&mut self, number: usize) -> &mut Self {
+ self.raw.start_number = number;
+ self
+ }
+
+ /// Set the "re-roll" number.
+ ///
+ /// The default value for this is 0 (no re-roll).
+ pub fn reroll_number(&mut self, number: usize) -> &mut Self {
+ self.raw.reroll_number = number;
+ self
+ }
+
+ /// Acquire a pointer to the underlying raw options.
+ ///
+ /// This function is unsafe as the pointer is only valid so long as this
+ /// structure is not moved, modified, or used elsewhere.
+ unsafe fn raw(&mut self) -> *const raw::git_email_create_options {
+ self.raw.subject_prefix = self
+ .subject_prefix
+ .as_ref()
+ .map(|s| s.as_ptr())
+ .unwrap_or(ptr::null());
+ self.raw.diff_opts = ptr::read(self.diff_options.raw());
+ self.raw.diff_find_opts = ptr::read(self.diff_find_options.raw());
+ &self.raw as *const _
+ }
+}
+
+impl Email {
+ /// Returns a byte slice with stored e-mail patch in. `Email` could be
+ /// created by one of the `from_*` functions.
+ pub fn as_slice(&self) -> &[u8] {
+ &self.buf
+ }
+
+ /// Create a diff for a commit in mbox format for sending via email.
+ pub fn from_diff<T: IntoCString>(
+ diff: &Diff<'_>,
+ patch_idx: usize,
+ patch_count: usize,
+ commit_id: &Oid,
+ summary: T,
+ body: T,
+ author: &Signature<'_>,
+ opts: &mut EmailCreateOptions,
+ ) -> Result<Self, Error> {
+ let buf = Buf::new();
+ let summary = summary.into_c_string()?;
+ let body = body.into_c_string()?;
+ unsafe {
+ try_call!(raw::git_email_create_from_diff(
+ buf.raw(),
+ Binding::raw(diff),
+ patch_idx,
+ patch_count,
+ Binding::raw(commit_id),
+ summary.as_ptr(),
+ body.as_ptr(),
+ Binding::raw(author),
+ opts.raw()
+ ));
+ Ok(Self { buf })
+ }
+ }
+
+ /// Create a diff for a commit in mbox format for sending via email.
+ /// The commit must not be a merge commit.
+ pub fn from_commit(commit: &Commit<'_>, opts: &mut EmailCreateOptions) -> Result<Self, Error> {
+ let buf = Buf::new();
+ unsafe {
+ try_call!(raw::git_email_create_from_commit(
+ buf.raw(),
+ commit.raw(),
+ opts.raw()
+ ));
+ Ok(Self { buf })
+ }
+ }
+}