Show More
@@ -0,0 +1,36 b'' | |||||
|
1 | pub mod dirs_multiset; | |||
|
2 | pub mod parsers; | |||
|
3 | ||||
|
4 | #[derive(Debug, PartialEq, Copy, Clone)] | |||
|
5 | pub struct DirstateParents<'a> { | |||
|
6 | pub p1: &'a [u8], | |||
|
7 | pub p2: &'a [u8], | |||
|
8 | } | |||
|
9 | ||||
|
10 | /// The C implementation uses all signed types. This will be an issue | |||
|
11 | /// either when 4GB+ source files are commonplace or in 2038, whichever | |||
|
12 | /// comes first. | |||
|
13 | #[derive(Debug, PartialEq)] | |||
|
14 | pub struct DirstateEntry { | |||
|
15 | pub state: i8, | |||
|
16 | pub mode: i32, | |||
|
17 | pub mtime: i32, | |||
|
18 | pub size: i32, | |||
|
19 | } | |||
|
20 | ||||
|
21 | pub type DirstateVec = Vec<(Vec<u8>, DirstateEntry)>; | |||
|
22 | ||||
|
23 | #[derive(Debug, PartialEq)] | |||
|
24 | pub struct CopyVecEntry<'a> { | |||
|
25 | pub path: &'a [u8], | |||
|
26 | pub copy_path: &'a [u8], | |||
|
27 | } | |||
|
28 | ||||
|
29 | pub type CopyVec<'a> = Vec<CopyVecEntry<'a>>; | |||
|
30 | ||||
|
31 | /// The Python implementation passes either a mapping (dirstate) or a flat | |||
|
32 | /// iterable (manifest) | |||
|
33 | pub enum DirsIterable { | |||
|
34 | Dirstate(DirstateVec), | |||
|
35 | Manifest(Vec<Vec<u8>>), | |||
|
36 | } |
@@ -0,0 +1,45 b'' | |||||
|
1 | pub mod files; | |||
|
2 | ||||
|
3 | pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T]) | |||
|
4 | where | |||
|
5 | T: Clone + PartialEq, | |||
|
6 | { | |||
|
7 | if buf.len() < from.len() || from.len() != to.len() { | |||
|
8 | return; | |||
|
9 | } | |||
|
10 | for i in 0..=buf.len() - from.len() { | |||
|
11 | if buf[i..].starts_with(from) { | |||
|
12 | buf[i..(i + from.len())].clone_from_slice(to); | |||
|
13 | } | |||
|
14 | } | |||
|
15 | } | |||
|
16 | ||||
|
17 | pub trait SliceExt { | |||
|
18 | fn trim(&self) -> &Self; | |||
|
19 | fn trim_end(&self) -> &Self; | |||
|
20 | } | |||
|
21 | ||||
|
22 | fn is_not_whitespace(c: &u8) -> bool { | |||
|
23 | !(*c as char).is_whitespace() | |||
|
24 | } | |||
|
25 | ||||
|
26 | impl SliceExt for [u8] { | |||
|
27 | fn trim(&self) -> &[u8] { | |||
|
28 | if let Some(first) = self.iter().position(is_not_whitespace) { | |||
|
29 | if let Some(last) = self.iter().rposition(is_not_whitespace) { | |||
|
30 | &self[first..last + 1] | |||
|
31 | } else { | |||
|
32 | unreachable!(); | |||
|
33 | } | |||
|
34 | } else { | |||
|
35 | &[] | |||
|
36 | } | |||
|
37 | } | |||
|
38 | fn trim_end(&self) -> &[u8] { | |||
|
39 | if let Some(last) = self.iter().rposition(is_not_whitespace) { | |||
|
40 | &self[..last + 1] | |||
|
41 | } else { | |||
|
42 | &[] | |||
|
43 | } | |||
|
44 | } | |||
|
45 | } |
@@ -3,6 +3,7 b' name = "hg-core"' | |||||
3 | version = "0.1.0" |
|
3 | version = "0.1.0" | |
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] |
|
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] | |
5 | description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)" |
|
5 | description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)" | |
|
6 | edition = "2018" | |||
6 |
|
7 | |||
7 | [lib] |
|
8 | [lib] | |
8 | name = "hg" |
|
9 | name = "hg" |
@@ -8,10 +8,9 b'' | |||||
8 | //! A multiset of directory names. |
|
8 | //! A multiset of directory names. | |
9 | //! |
|
9 | //! | |
10 | //! Used to counts the references to directories in a manifest or dirstate. |
|
10 | //! Used to counts the references to directories in a manifest or dirstate. | |
|
11 | use crate::{utils::files, DirsIterable, DirstateEntry, DirstateMapError}; | |||
11 | use std::collections::hash_map::{Entry, Iter}; |
|
12 | use std::collections::hash_map::{Entry, Iter}; | |
12 | use std::collections::HashMap; |
|
13 | use std::collections::HashMap; | |
13 | use {DirsIterable, DirstateEntry, DirstateMapError}; |
|
|||
14 | use utils::files; |
|
|||
15 |
|
14 | |||
16 | #[derive(PartialEq, Debug)] |
|
15 | #[derive(PartialEq, Debug)] | |
17 | pub struct DirsMultiset { |
|
16 | pub struct DirsMultiset { |
@@ -3,13 +3,13 b'' | |||||
3 | // This software may be used and distributed according to the terms of the |
|
3 | // This software may be used and distributed according to the terms of the | |
4 | // GNU General Public License version 2 or any later version. |
|
4 | // GNU General Public License version 2 or any later version. | |
5 |
|
5 | |||
|
6 | use crate::{ | |||
|
7 | CopyVec, CopyVecEntry, DirstateEntry, DirstatePackError, DirstateParents, | |||
|
8 | DirstateParseError, DirstateVec, | |||
|
9 | }; | |||
6 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; |
|
10 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; | |
7 | use std::collections::HashMap; |
|
11 | use std::collections::HashMap; | |
8 | use std::io::Cursor; |
|
12 | use std::io::Cursor; | |
9 | use { |
|
|||
10 | CopyVec, CopyVecEntry, DirstateEntry, DirstatePackError, DirstateParents, |
|
|||
11 | DirstateParseError, DirstateVec, |
|
|||
12 | }; |
|
|||
13 |
|
13 | |||
14 | /// Parents are stored in the dirstate as byte hashes. |
|
14 | /// Parents are stored in the dirstate as byte hashes. | |
15 | const PARENT_SIZE: usize = 20; |
|
15 | const PARENT_SIZE: usize = 20; |
@@ -1,11 +1,13 b'' | |||||
1 | use crate::{LineNumber, PatternError, PatternFileError}; |
|
1 | use crate::{ | |
|
2 | utils::{files::get_path_from_bytes, replace_slice, SliceExt}, | |||
|
3 | LineNumber, PatternError, PatternFileError, | |||
|
4 | }; | |||
|
5 | use lazy_static::lazy_static; | |||
2 | use regex::bytes::Regex; |
|
6 | use regex::bytes::Regex; | |
3 | use std::collections::HashMap; |
|
7 | use std::collections::HashMap; | |
4 | use std::fs::File; |
|
8 | use std::fs::File; | |
5 | use std::io::Read; |
|
9 | use std::io::Read; | |
6 | use std::vec::Vec; |
|
10 | use std::vec::Vec; | |
7 | use utils::files::get_path_from_bytes; |
|
|||
8 | use utils::{replace_slice, SliceExt}; |
|
|||
9 |
|
11 | |||
10 | lazy_static! { |
|
12 | lazy_static! { | |
11 | static ref RE_ESCAPE: Vec<Vec<u8>> = { |
|
13 | static ref RE_ESCAPE: Vec<Vec<u8>> = { |
@@ -2,12 +2,6 b'' | |||||
2 | // |
|
2 | // | |
3 | // This software may be used and distributed according to the terms of the |
|
3 | // This software may be used and distributed according to the terms of the | |
4 | // GNU General Public License version 2 or any later version. |
|
4 | // GNU General Public License version 2 or any later version. | |
5 | extern crate byteorder; |
|
|||
6 | extern crate memchr; |
|
|||
7 | #[macro_use] |
|
|||
8 | extern crate lazy_static; |
|
|||
9 | extern crate regex; |
|
|||
10 |
|
||||
11 | mod ancestors; |
|
5 | mod ancestors; | |
12 | pub mod dagops; |
|
6 | pub mod dagops; | |
13 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; |
|
7 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; | |
@@ -50,7 +44,7 b' pub trait Graph {' | |||||
50 | /// Return the two parents of the given `Revision`. |
|
44 | /// Return the two parents of the given `Revision`. | |
51 | /// |
|
45 | /// | |
52 | /// Each of the parents can be independently `NULL_REVISION` |
|
46 | /// Each of the parents can be independently `NULL_REVISION` | |
53 | fn parents(&self, Revision) -> Result<[Revision; 2], GraphError>; |
|
47 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>; | |
54 | } |
|
48 | } | |
55 |
|
49 | |||
56 | pub type LineNumber = usize; |
|
50 | pub type LineNumber = usize; |
@@ -1,7 +1,3 b'' | |||||
1 | extern crate hg; |
|
|||
2 | extern crate rand; |
|
|||
3 | extern crate rand_pcg; |
|
|||
4 |
|
||||
5 |
|
|
1 | use hg::testing::VecGraph; | |
6 | use hg::Revision; |
|
2 | use hg::Revision; | |
7 | use hg::*; |
|
3 | use hg::*; |
@@ -2,6 +2,7 b'' | |||||
2 | name = "hg-cpython" |
|
2 | name = "hg-cpython" | |
3 | version = "0.1.0" |
|
3 | version = "0.1.0" | |
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] |
|
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] | |
|
5 | edition = "2018" | |||
5 |
|
6 | |||
6 | [lib] |
|
7 | [lib] | |
7 | name='rusthg' |
|
8 | name='rusthg' |
@@ -34,13 +34,15 b'' | |||||
34 | //! [`LazyAncestors`]: struct.LazyAncestors.html |
|
34 | //! [`LazyAncestors`]: struct.LazyAncestors.html | |
35 | //! [`MissingAncestors`]: struct.MissingAncestors.html |
|
35 | //! [`MissingAncestors`]: struct.MissingAncestors.html | |
36 | //! [`AncestorsIterator`]: struct.AncestorsIterator.html |
|
36 | //! [`AncestorsIterator`]: struct.AncestorsIterator.html | |
37 | use crate::conversion::{py_set, rev_pyiter_collect}; |
|
37 | use crate::{ | |
38 |
|
|
38 | cindex::Index, | |
|
39 | conversion::{py_set, rev_pyiter_collect}, | |||
|
40 | exceptions::GraphError, | |||
|
41 | }; | |||
39 | use cpython::{ |
|
42 | use cpython::{ | |
40 | ObjectProtocol, PyClone, PyDict, PyList, PyModule, PyObject, PyResult, |
|
43 | ObjectProtocol, PyClone, PyDict, PyList, PyModule, PyObject, PyResult, | |
41 | Python, PythonObject, ToPyObject, |
|
44 | Python, PythonObject, ToPyObject, | |
42 | }; |
|
45 | }; | |
43 | use exceptions::GraphError; |
|
|||
44 | use hg::Revision; |
|
46 | use hg::Revision; | |
45 | use hg::{ |
|
47 | use hg::{ | |
46 | AncestorsIterator as CoreIterator, LazyAncestors as CoreLazy, |
|
48 | AncestorsIterator as CoreIterator, LazyAncestors as CoreLazy, |
@@ -10,14 +10,14 b'' | |||||
10 | //! Ideally, we should use an Index entirely implemented in Rust, |
|
10 | //! Ideally, we should use an Index entirely implemented in Rust, | |
11 | //! but this will take some time to get there. |
|
11 | //! but this will take some time to get there. | |
12 | #[cfg(feature = "python27")] |
|
12 | #[cfg(feature = "python27")] | |
13 |
|
|
13 | use python27_sys as python_sys; | |
14 | #[cfg(feature = "python3")] |
|
14 | #[cfg(feature = "python3")] | |
15 |
|
|
15 | use python3_sys as python_sys; | |
16 |
|
16 | |||
17 | use self::python_sys::PyCapsule_Import; |
|
|||
18 | use cpython::{PyClone, PyErr, PyObject, PyResult, Python}; |
|
17 | use cpython::{PyClone, PyErr, PyObject, PyResult, Python}; | |
19 | use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; |
|
18 | use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; | |
20 | use libc::c_int; |
|
19 | use libc::c_int; | |
|
20 | use python_sys::PyCapsule_Import; | |||
21 | use std::ffi::CStr; |
|
21 | use std::ffi::CStr; | |
22 | use std::mem::transmute; |
|
22 | use std::mem::transmute; | |
23 |
|
23 |
@@ -9,10 +9,12 b'' | |||||
9 | //! `hg-core` package. |
|
9 | //! `hg-core` package. | |
10 | //! |
|
10 | //! | |
11 | //! From Python, this will be seen as `mercurial.rustext.dagop` |
|
11 | //! From Python, this will be seen as `mercurial.rustext.dagop` | |
12 | use crate::conversion::{py_set, rev_pyiter_collect}; |
|
12 | use crate::{ | |
13 |
|
|
13 | cindex::Index, | |
|
14 | conversion::{py_set, rev_pyiter_collect}, | |||
|
15 | exceptions::GraphError, | |||
|
16 | }; | |||
14 | use cpython::{PyDict, PyModule, PyObject, PyResult, Python}; |
|
17 | use cpython::{PyDict, PyModule, PyObject, PyResult, Python}; | |
15 | use exceptions::GraphError; |
|
|||
16 | use hg::dagops; |
|
18 | use hg::dagops; | |
17 | use hg::Revision; |
|
19 | use hg::Revision; | |
18 | use std::collections::HashSet; |
|
20 | use std::collections::HashSet; |
@@ -19,17 +19,14 b' use hg::{' | |||||
19 | DirstateEntry, DirstateMapError, DirstatePackError, DirstateParents, |
|
19 | DirstateEntry, DirstateMapError, DirstatePackError, DirstateParents, | |
20 | DirstateParseError, DirstateVec, |
|
20 | DirstateParseError, DirstateVec, | |
21 | }; |
|
21 | }; | |
|
22 | use libc::{c_char, c_int}; | |||
|
23 | #[cfg(feature = "python27")] | |||
|
24 | use python27_sys::PyCapsule_Import; | |||
|
25 | #[cfg(feature = "python3")] | |||
|
26 | use python3_sys::PyCapsule_Import; | |||
|
27 | use std::cell::RefCell; | |||
22 | use std::collections::HashMap; |
|
28 | use std::collections::HashMap; | |
23 | use std::ffi::CStr; |
|
29 | use std::ffi::CStr; | |
24 |
|
||||
25 | #[cfg(feature = "python27")] |
|
|||
26 | extern crate python27_sys as python_sys; |
|
|||
27 | #[cfg(feature = "python3")] |
|
|||
28 | extern crate python3_sys as python_sys; |
|
|||
29 |
|
||||
30 | use self::python_sys::PyCapsule_Import; |
|
|||
31 | use libc::{c_char, c_int}; |
|
|||
32 | use std::cell::RefCell; |
|
|||
33 | use std::mem::transmute; |
|
30 | use std::mem::transmute; | |
34 |
|
31 | |||
35 | /// C code uses a custom `dirstate_tuple` type, checks in multiple instances |
|
32 | /// C code uses a custom `dirstate_tuple` type, checks in multiple instances |
@@ -12,13 +12,15 b'' | |||||
12 | //! - [`PartialDiscover`] is the Rust implementation of |
|
12 | //! - [`PartialDiscover`] is the Rust implementation of | |
13 | //! `mercurial.setdiscovery.partialdiscovery`. |
|
13 | //! `mercurial.setdiscovery.partialdiscovery`. | |
14 |
|
14 | |||
15 | use crate::conversion::{py_set, rev_pyiter_collect}; |
|
15 | use crate::{ | |
16 |
|
|
16 | cindex::Index, | |
|
17 | conversion::{py_set, rev_pyiter_collect}, | |||
|
18 | exceptions::GraphError, | |||
|
19 | }; | |||
17 | use cpython::{ |
|
20 | use cpython::{ | |
18 | ObjectProtocol, PyDict, PyModule, PyObject, PyResult, Python, |
|
21 | ObjectProtocol, PyDict, PyModule, PyObject, PyResult, Python, | |
19 | PythonObject, ToPyObject, |
|
22 | PythonObject, ToPyObject, | |
20 | }; |
|
23 | }; | |
21 | use exceptions::GraphError; |
|
|||
22 | use hg::discovery::PartialDiscovery as CorePartialDiscovery; |
|
24 | use hg::discovery::PartialDiscovery as CorePartialDiscovery; | |
23 | use hg::Revision; |
|
25 | use hg::Revision; | |
24 |
|
26 |
@@ -12,8 +12,10 b'' | |||||
12 | //! existing Python exceptions if appropriate. |
|
12 | //! existing Python exceptions if appropriate. | |
13 | //! |
|
13 | //! | |
14 | //! [`GraphError`]: struct.GraphError.html |
|
14 | //! [`GraphError`]: struct.GraphError.html | |
15 | use cpython::exc::{RuntimeError, ValueError}; |
|
15 | use cpython::{ | |
16 | use cpython::{exc, PyErr, Python}; |
|
16 | exc::{IOError, RuntimeError, ValueError}, | |
|
17 | py_exception, PyErr, Python, | |||
|
18 | }; | |||
17 | use hg; |
|
19 | use hg; | |
18 |
|
20 | |||
19 | py_exception!(rustext, GraphError, ValueError); |
|
21 | py_exception!(rustext, GraphError, ValueError); | |
@@ -55,7 +57,7 b' impl PatternFileError {' | |||||
55 | match inner { |
|
57 | match inner { | |
56 | hg::PatternFileError::IO(e) => { |
|
58 | hg::PatternFileError::IO(e) => { | |
57 | let value = (e.raw_os_error().unwrap_or(2), e.to_string()); |
|
59 | let value = (e.raw_os_error().unwrap_or(2), e.to_string()); | |
58 |
PyErr::new::< |
|
60 | PyErr::new::<IOError, _>(py, value) | |
59 | } |
|
61 | } | |
60 | hg::PatternFileError::Pattern(e, l) => match e { |
|
62 | hg::PatternFileError::Pattern(e, l) => match e { | |
61 | hg::PatternError::UnsupportedSyntax(m) => { |
|
63 | hg::PatternError::UnsupportedSyntax(m) => { |
@@ -10,10 +10,10 b'' | |||||
10 | //! `hg-core` crate. From Python, this will be seen as `rustext.filepatterns` |
|
10 | //! `hg-core` crate. From Python, this will be seen as `rustext.filepatterns` | |
11 | //! and can be used as replacement for the the pure `filepatterns` Python module. |
|
11 | //! and can be used as replacement for the the pure `filepatterns` Python module. | |
12 | //! |
|
12 | //! | |
|
13 | use crate::exceptions::{PatternError, PatternFileError}; | |||
13 | use cpython::{ |
|
14 | use cpython::{ | |
14 | PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject, |
|
15 | PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject, | |
15 | }; |
|
16 | }; | |
16 | use exceptions::{PatternError, PatternFileError}; |
|
|||
17 | use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple}; |
|
17 | use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple}; | |
18 |
|
18 | |||
19 | /// Rust does not like functions with different return signatures. |
|
19 | /// Rust does not like functions with different return signatures. |
@@ -19,10 +19,10 b'' | |||||
19 | //! 'Generic DAG ancestor algorithms - Rust implementation' |
|
19 | //! 'Generic DAG ancestor algorithms - Rust implementation' | |
20 | //! ``` |
|
20 | //! ``` | |
21 |
|
21 | |||
|
22 | /// This crate uses nested private macros, `extern crate` is still needed in | |||
|
23 | /// 2018 edition. | |||
22 | #[macro_use] |
|
24 | #[macro_use] | |
23 | extern crate cpython; |
|
25 | extern crate cpython; | |
24 | extern crate hg; |
|
|||
25 | extern crate libc; |
|
|||
26 |
|
26 | |||
27 | pub mod ancestors; |
|
27 | pub mod ancestors; | |
28 | mod cindex; |
|
28 | mod cindex; |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now