libgit2-rs-safe: Update for 2nd edition.

pull/13/head
Jim Blandy 3 years ago
parent cd2e8fd8ab
commit f1efa660ca

@ -2,7 +2,7 @@
name = "git-toy" name = "git-toy"
version = "0.1.0" version = "0.1.0"
authors = ["You <you@example.com>"] authors = ["You <you@example.com>"]
build = "build.rs" edition = "2018"
[dependencies] [dependencies]
libc = "0.2.23" libc = "0.2"

@ -18,9 +18,7 @@ impl fmt::Display for Error {
} }
} }
impl error::Error for Error { impl error::Error for Error { }
fn description(&self) -> &str { &self.message }
}
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
@ -51,19 +49,20 @@ fn check(code: c_int) -> Result<c_int> {
/// A Git repository. /// A Git repository.
pub struct Repository { pub struct Repository {
// This must always be a pointer to a live `git_repository` structure, // This must always be a pointer to a live `git_repository` structure.
// No other `Repository` may point to it. // No other `Repository` may point to it.
raw: *mut raw::git_repository raw: *mut raw::git_repository
} }
use std::path::Path; use std::path::Path;
use std::ptr;
impl Repository { impl Repository {
pub fn open<P: AsRef<Path>>(path: P) -> Result<Repository> { pub fn open<P: AsRef<Path>>(path: P) -> Result<Repository> {
ensure_initialized(); ensure_initialized();
let path = path_to_cstring(path.as_ref())?; let path = path_to_cstring(path.as_ref())?;
let mut repo = null_mut(); let mut repo = ptr::null_mut();
unsafe { unsafe {
check(raw::git_repository_open(&mut repo, path.as_ptr()))?; check(raw::git_repository_open(&mut repo, path.as_ptr()))?;
} }
@ -71,9 +70,6 @@ impl Repository {
} }
} }
use std;
use libc;
fn ensure_initialized() { fn ensure_initialized() {
static ONCE: std::sync::Once = std::sync::Once::new(); static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| { ONCE.call_once(|| {
@ -85,14 +81,10 @@ fn ensure_initialized() {
}); });
} }
use std::io::Write;
extern fn shutdown() { extern fn shutdown() {
unsafe { unsafe {
if let Err(e) = check(raw::git_libgit2_shutdown()) { if let Err(e) = check(raw::git_libgit2_shutdown()) {
let _ = writeln!(std::io::stderr(), eprintln!("shutting down libgit2 failed: {}", e);
"shutting down libgit2 failed: {}",
e);
std::process::abort(); std::process::abort();
} }
} }
@ -151,16 +143,20 @@ pub struct Oid {
pub raw: raw::git_oid pub raw: raw::git_oid
} }
use std::mem::uninitialized; use std::mem;
use std::os::raw::c_char; use std::os::raw::c_char;
impl Repository { impl Repository {
pub fn reference_name_to_id(&self, name: &str) -> Result<Oid> { pub fn reference_name_to_id(&self, name: &str) -> Result<Oid> {
let name = CString::new(name)?; let name = CString::new(name)?;
unsafe { unsafe {
let mut oid = uninitialized(); let oid = {
check(raw::git_reference_name_to_id(&mut oid, self.raw, let mut oid = mem::MaybeUninit::uninit();
name.as_ptr() as *const c_char))?; check(raw::git_reference_name_to_id(
oid.as_mut_ptr(), self.raw,
name.as_ptr() as *const c_char))?;
oid.assume_init()
};
Ok(Oid { raw: oid }) Ok(Oid { raw: oid })
} }
} }
@ -174,11 +170,9 @@ pub struct Commit<'repo> {
_marker: PhantomData<&'repo Repository> _marker: PhantomData<&'repo Repository>
} }
use std::ptr::null_mut;
impl Repository { impl Repository {
pub fn find_commit(&self, oid: &Oid) -> Result<Commit> { pub fn find_commit(&self, oid: &Oid) -> Result<Commit> {
let mut commit = null_mut(); let mut commit = ptr::null_mut();
unsafe { unsafe {
check(raw::git_commit_lookup(&mut commit, self.raw, &oid.raw))?; check(raw::git_commit_lookup(&mut commit, self.raw, &oid.raw))?;
} }
@ -240,7 +234,8 @@ impl<'text> Signature<'text> {
/// borrowed from `_owner`. /// borrowed from `_owner`.
/// ///
/// Safety: if `ptr` is non-null, it must point to a null-terminated C /// Safety: if `ptr` is non-null, it must point to a null-terminated C
/// string that is safe to access. /// string that is safe to access for at least as long as the lifetime of
/// `_owner`.
unsafe fn char_ptr_to_str<T>(_owner: &T, ptr: *const c_char) -> Option<&str> { unsafe fn char_ptr_to_str<T>(_owner: &T, ptr: *const c_char) -> Option<&str> {
if ptr.is_null() { if ptr.is_null() {
return None; return None;

@ -1,10 +1,11 @@
mod git; #![warn(rust_2018_idioms)]
#![allow(elided_lifetimes_in_paths)]
extern crate libc; mod git;
fn main() { fn main() {
let path = std::env::args_os().skip(1).next() let path = std::env::args_os().skip(1).next()
.expect("usage: libgit2-rs PATH"); .expect("usage: git-toy PATH");
let repo = git::Repository::open(&path) let repo = git::Repository::open(&path)
.expect("opening repository"); .expect("opening repository");

Loading…
Cancel
Save