Instead of plain byte arrays.
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
( )
Instead of plain byte arrays.
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | rust/hg-core/src/dirstate.rs (5 lines) | |||
| M | rust/hg-core/src/dirstate/dirstate_map.rs (10 lines) | |||
| M | rust/hg-core/src/dirstate/parsers.rs (28 lines) | |||
| M | rust/hg-core/src/revlog/node.rs (7 lines) | |||
| M | rust/hg-cpython/src/dirstate/dirstate_map.rs (16 lines) | |||
| M | rust/hg-cpython/src/parsers.rs (14 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| ff795feb8636 | 89446160fa1b | Simon Sapin | Feb 17 2021, 6:24 AM |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin |
| // dirstate module | // dirstate module | ||||
| // | // | ||||
| // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | ||||
| // | // | ||||
| // This software may be used and distributed according to the terms of the | // This software may be used and distributed according to the terms of the | ||||
| // GNU General Public License version 2 or any later version. | // GNU General Public License version 2 or any later version. | ||||
| use crate::errors::HgError; | use crate::errors::HgError; | ||||
| use crate::revlog::Node; | |||||
| use crate::{utils::hg_path::HgPathBuf, FastHashMap}; | use crate::{utils::hg_path::HgPathBuf, FastHashMap}; | ||||
| use bytes_cast::{unaligned, BytesCast}; | use bytes_cast::{unaligned, BytesCast}; | ||||
| use std::collections::hash_map; | use std::collections::hash_map; | ||||
| use std::convert::TryFrom; | use std::convert::TryFrom; | ||||
| pub mod dirs_multiset; | pub mod dirs_multiset; | ||||
| pub mod dirstate_map; | pub mod dirstate_map; | ||||
| #[cfg(feature = "dirstate-tree")] | #[cfg(feature = "dirstate-tree")] | ||||
| pub mod dirstate_tree; | pub mod dirstate_tree; | ||||
| pub mod parsers; | pub mod parsers; | ||||
| pub mod status; | pub mod status; | ||||
| #[derive(Debug, PartialEq, Clone, BytesCast)] | #[derive(Debug, PartialEq, Clone, BytesCast)] | ||||
| #[repr(C)] | #[repr(C)] | ||||
| pub struct DirstateParents { | pub struct DirstateParents { | ||||
| pub p1: [u8; 20], | pub p1: Node, | ||||
| pub p2: [u8; 20], | pub p2: Node, | ||||
| } | } | ||||
| /// The C implementation uses all signed types. This will be an issue | /// The C implementation uses all signed types. This will be an issue | ||||
| /// either when 4GB+ source files are commonplace or in 2038, whichever | /// either when 4GB+ source files are commonplace or in 2038, whichever | ||||
| /// comes first. | /// comes first. | ||||
| #[derive(Debug, PartialEq, Copy, Clone)] | #[derive(Debug, PartialEq, Copy, Clone)] | ||||
| pub struct DirstateEntry { | pub struct DirstateEntry { | ||||
| pub state: EntryState, | pub state: EntryState, | ||||
| // dirstate_map.rs | // dirstate_map.rs | ||||
| // | // | ||||
| // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | ||||
| // | // | ||||
| // This software may be used and distributed according to the terms of the | // This software may be used and distributed according to the terms of the | ||||
| // GNU General Public License version 2 or any later version. | // GNU General Public License version 2 or any later version. | ||||
| use crate::errors::HgError; | use crate::errors::HgError; | ||||
| use crate::revlog::node::NULL_NODE_ID; | use crate::revlog::node::NULL_NODE; | ||||
| use crate::{ | use crate::{ | ||||
| dirstate::{parsers::PARENT_SIZE, EntryState, SIZE_FROM_OTHER_PARENT}, | dirstate::{parsers::PARENT_SIZE, EntryState, SIZE_FROM_OTHER_PARENT}, | ||||
| pack_dirstate, parse_dirstate, | pack_dirstate, parse_dirstate, | ||||
| utils::{ | utils::{ | ||||
| files::normalize_case, | files::normalize_case, | ||||
| hg_path::{HgPath, HgPathBuf}, | hg_path::{HgPath, HgPathBuf}, | ||||
| }, | }, | ||||
| CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateMapError, | CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateMapError, | ||||
| pub fn clear(&mut self) { | pub fn clear(&mut self) { | ||||
| self.state_map = StateMap::default(); | self.state_map = StateMap::default(); | ||||
| self.copy_map.clear(); | self.copy_map.clear(); | ||||
| self.file_fold_map = None; | self.file_fold_map = None; | ||||
| self.non_normal_set = None; | self.non_normal_set = None; | ||||
| self.other_parent_set = None; | self.other_parent_set = None; | ||||
| self.set_parents(&DirstateParents { | self.set_parents(&DirstateParents { | ||||
| p1: NULL_NODE_ID, | p1: NULL_NODE, | ||||
| p2: NULL_NODE_ID, | p2: NULL_NODE, | ||||
| }) | }) | ||||
| } | } | ||||
| /// Add a tracked file to the dirstate | /// Add a tracked file to the dirstate | ||||
| pub fn add_file( | pub fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| old_state: EntryState, | old_state: EntryState, | ||||
| parents = DirstateParents { | parents = DirstateParents { | ||||
| p1: file_contents[..PARENT_SIZE].try_into().unwrap(), | p1: file_contents[..PARENT_SIZE].try_into().unwrap(), | ||||
| p2: file_contents[PARENT_SIZE..PARENT_SIZE * 2] | p2: file_contents[PARENT_SIZE..PARENT_SIZE * 2] | ||||
| .try_into() | .try_into() | ||||
| .unwrap(), | .unwrap(), | ||||
| }; | }; | ||||
| } else if file_contents.is_empty() { | } else if file_contents.is_empty() { | ||||
| parents = DirstateParents { | parents = DirstateParents { | ||||
| p1: NULL_NODE_ID, | p1: NULL_NODE, | ||||
| p2: NULL_NODE_ID, | p2: NULL_NODE, | ||||
| }; | }; | ||||
| } else { | } else { | ||||
| return Err( | return Err( | ||||
| HgError::corrupted("Dirstate appears to be damaged").into() | HgError::corrupted("Dirstate appears to be damaged").into() | ||||
| ); | ); | ||||
| } | } | ||||
| self.parents = Some(parents); | self.parents = Some(parents); | ||||
| } | } | ||||
| length | length | ||||
| }) | }) | ||||
| .sum(); | .sum(); | ||||
| let expected_size = expected_size + PARENT_SIZE * 2; | let expected_size = expected_size + PARENT_SIZE * 2; | ||||
| let mut packed = Vec::with_capacity(expected_size); | let mut packed = Vec::with_capacity(expected_size); | ||||
| packed.extend(&parents.p1); | packed.extend(parents.p1.as_bytes()); | ||||
| packed.extend(&parents.p2); | packed.extend(parents.p2.as_bytes()); | ||||
| for (filename, entry) in state_map.iter_mut() { | for (filename, entry) in state_map.iter_mut() { | ||||
| let new_filename = filename.to_owned(); | let new_filename = filename.to_owned(); | ||||
| let mut new_mtime: i32 = entry.mtime; | let mut new_mtime: i32 = entry.mtime; | ||||
| if entry.state == EntryState::Normal && entry.mtime == now { | if entry.state == EntryState::Normal && entry.mtime == now { | ||||
| // The file was last modified "simultaneously" with the current | // The file was last modified "simultaneously" with the current | ||||
| // write to dirstate (i.e. within the same second for file- | // write to dirstate (i.e. within the same second for file- | ||||
| // systems with a granularity of 1 sec). This commonly happens | // systems with a granularity of 1 sec). This commonly happens | ||||
| use crate::{utils::hg_path::HgPathBuf, FastHashMap}; | use crate::{utils::hg_path::HgPathBuf, FastHashMap}; | ||||
| use pretty_assertions::assert_eq; | use pretty_assertions::assert_eq; | ||||
| #[test] | #[test] | ||||
| fn test_pack_dirstate_empty() { | fn test_pack_dirstate_empty() { | ||||
| let mut state_map = StateMap::default(); | let mut state_map = StateMap::default(); | ||||
| let copymap = FastHashMap::default(); | let copymap = FastHashMap::default(); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let expected = b"1234567891011121314100000000000000000000".to_vec(); | let expected = b"1234567891011121314100000000000000000000".to_vec(); | ||||
| assert_eq!( | assert_eq!( | ||||
| expected, | expected, | ||||
| pack_dirstate(&mut state_map, ©map, parents, now).unwrap() | pack_dirstate(&mut state_map, ©map, parents, now).unwrap() | ||||
| ); | ); | ||||
| )] | )] | ||||
| .iter() | .iter() | ||||
| .cloned() | .cloned() | ||||
| .collect(); | .collect(); | ||||
| let mut state_map = expected_state_map.clone(); | let mut state_map = expected_state_map.clone(); | ||||
| let copymap = FastHashMap::default(); | let copymap = FastHashMap::default(); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let expected = [ | let expected = [ | ||||
| 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49, | 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49, | ||||
| 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, | 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, | ||||
| 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47, | 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47, | ||||
| 41, 58, 244, 0, 0, 0, 2, 102, 49, | 41, 58, 244, 0, 0, 0, 2, 102, 49, | ||||
| ] | ] | ||||
| .collect(); | .collect(); | ||||
| let mut state_map = expected_state_map.clone(); | let mut state_map = expected_state_map.clone(); | ||||
| let mut copymap = FastHashMap::default(); | let mut copymap = FastHashMap::default(); | ||||
| copymap.insert( | copymap.insert( | ||||
| HgPathBuf::from_bytes(b"f1"), | HgPathBuf::from_bytes(b"f1"), | ||||
| HgPathBuf::from_bytes(b"copyname"), | HgPathBuf::from_bytes(b"copyname"), | ||||
| ); | ); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let expected = [ | let expected = [ | ||||
| 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49, | 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49, | ||||
| 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, | 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, | ||||
| 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47, | 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47, | ||||
| 41, 58, 244, 0, 0, 0, 11, 102, 49, 0, 99, 111, 112, 121, 110, 97, | 41, 58, 244, 0, 0, 0, 11, 102, 49, 0, 99, 111, 112, 121, 110, 97, | ||||
| 109, 101, | 109, 101, | ||||
| .cloned() | .cloned() | ||||
| .collect(); | .collect(); | ||||
| let mut copymap = FastHashMap::default(); | let mut copymap = FastHashMap::default(); | ||||
| copymap.insert( | copymap.insert( | ||||
| HgPathBuf::from_bytes(b"f1"), | HgPathBuf::from_bytes(b"f1"), | ||||
| HgPathBuf::from_bytes(b"copyname"), | HgPathBuf::from_bytes(b"copyname"), | ||||
| ); | ); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let result = | let result = | ||||
| pack_dirstate(&mut state_map, ©map, parents.clone(), now) | pack_dirstate(&mut state_map, ©map, parents.clone(), now) | ||||
| .unwrap(); | .unwrap(); | ||||
| let (new_parents, entries, copies) = | let (new_parents, entries, copies) = | ||||
| parse_dirstate(result.as_slice()).unwrap(); | parse_dirstate(result.as_slice()).unwrap(); | ||||
| HgPathBuf::from_bytes(b"f1"), | HgPathBuf::from_bytes(b"f1"), | ||||
| HgPathBuf::from_bytes(b"copyname"), | HgPathBuf::from_bytes(b"copyname"), | ||||
| ); | ); | ||||
| copymap.insert( | copymap.insert( | ||||
| HgPathBuf::from_bytes(b"f4\xF6"), | HgPathBuf::from_bytes(b"f4\xF6"), | ||||
| HgPathBuf::from_bytes(b"copyname2"), | HgPathBuf::from_bytes(b"copyname2"), | ||||
| ); | ); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let result = | let result = | ||||
| pack_dirstate(&mut state_map, ©map, parents.clone(), now) | pack_dirstate(&mut state_map, ©map, parents.clone(), now) | ||||
| .unwrap(); | .unwrap(); | ||||
| let (new_parents, entries, copies) = | let (new_parents, entries, copies) = | ||||
| parse_dirstate(result.as_slice()).unwrap(); | parse_dirstate(result.as_slice()).unwrap(); | ||||
| .cloned() | .cloned() | ||||
| .collect(); | .collect(); | ||||
| let mut copymap = FastHashMap::default(); | let mut copymap = FastHashMap::default(); | ||||
| copymap.insert( | copymap.insert( | ||||
| HgPathBuf::from_bytes(b"f1"), | HgPathBuf::from_bytes(b"f1"), | ||||
| HgPathBuf::from_bytes(b"copyname"), | HgPathBuf::from_bytes(b"copyname"), | ||||
| ); | ); | ||||
| let parents = DirstateParents { | let parents = DirstateParents { | ||||
| p1: *b"12345678910111213141", | p1: b"12345678910111213141".into(), | ||||
| p2: *b"00000000000000000000", | p2: b"00000000000000000000".into(), | ||||
| }; | }; | ||||
| let now = Duration::new(15000000, 0); | let now = Duration::new(15000000, 0); | ||||
| let result = | let result = | ||||
| pack_dirstate(&mut state_map, ©map, parents.clone(), now) | pack_dirstate(&mut state_map, ©map, parents.clone(), now) | ||||
| .unwrap(); | .unwrap(); | ||||
| let (new_parents, entries, copies) = | let (new_parents, entries, copies) = | ||||
| parse_dirstate(result.as_slice()).unwrap(); | parse_dirstate(result.as_slice()).unwrap(); | ||||
| #[inline] | #[inline] | ||||
| fn try_from(bytes: &'_ [u8]) -> Result<Self, Self::Error> { | fn try_from(bytes: &'_ [u8]) -> Result<Self, Self::Error> { | ||||
| let data = bytes.try_into()?; | let data = bytes.try_into()?; | ||||
| Ok(Self { data }) | Ok(Self { data }) | ||||
| } | } | ||||
| } | } | ||||
| impl From<&'_ NodeData> for Node { | |||||
| #[inline] | |||||
| fn from(data: &'_ NodeData) -> Self { | |||||
| Self { data: *data } | |||||
| } | |||||
| } | |||||
| impl fmt::LowerHex for Node { | impl fmt::LowerHex for Node { | ||||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
| for &byte in &self.data { | for &byte in &self.data { | ||||
| write!(f, "{:02x}", byte)? | write!(f, "{:02x}", byte)? | ||||
| } | } | ||||
| Ok(()) | Ok(()) | ||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| use crate::{ | use crate::{ | ||||
| dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | ||||
| dirstate::non_normal_entries::{ | dirstate::non_normal_entries::{ | ||||
| NonNormalEntries, NonNormalEntriesIterator, | NonNormalEntries, NonNormalEntriesIterator, | ||||
| }, | }, | ||||
| dirstate::{dirs_multiset::Dirs, make_dirstate_tuple}, | dirstate::{dirs_multiset::Dirs, make_dirstate_tuple}, | ||||
| parsers::dirstate_parents_to_pytuple, | |||||
| }; | }; | ||||
| use hg::{ | use hg::{ | ||||
| errors::HgError, | errors::HgError, | ||||
| revlog::Node, | |||||
| utils::hg_path::{HgPath, HgPathBuf}, | utils::hg_path::{HgPath, HgPathBuf}, | ||||
| DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, | DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, | ||||
| DirstateMapError, DirstateParents, EntryState, StateMapIter, PARENT_SIZE, | DirstateMapError, DirstateParents, EntryState, StateMapIter, | ||||
| }; | }; | ||||
| // TODO | // TODO | ||||
| // This object needs to share references to multiple members of its Rust | // This object needs to share references to multiple members of its Rust | ||||
| // inner struct, namely `copy_map`, `dirs` and `all_dirs`. | // inner struct, namely `copy_map`, `dirs` and `all_dirs`. | ||||
| // Right now `CopyMap` is done, but it needs to have an explicit reference | // Right now `CopyMap` is done, but it needs to have an explicit reference | ||||
| // to `RustDirstateMap` which itself needs to have an encapsulation for | // to `RustDirstateMap` which itself needs to have an encapsulation for | ||||
| // every method in `CopyMap` (copymapcopy, etc.). | // every method in `CopyMap` (copymapcopy, etc.). | ||||
| PyErr::new::<exc::ValueError, _>(py, e.to_string()) | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | ||||
| })? | })? | ||||
| .to_py_object(py)) | .to_py_object(py)) | ||||
| } | } | ||||
| def parents(&self, st: PyObject) -> PyResult<PyTuple> { | def parents(&self, st: PyObject) -> PyResult<PyTuple> { | ||||
| self.inner(py).borrow_mut() | self.inner(py).borrow_mut() | ||||
| .parents(st.extract::<PyBytes>(py)?.data(py)) | .parents(st.extract::<PyBytes>(py)?.data(py)) | ||||
| .and_then(|d| { | .map(|parents| dirstate_parents_to_pytuple(py, parents)) | ||||
| Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2)) | |||||
| .to_py_object(py)) | |||||
| }) | |||||
| .or_else(|_| { | .or_else(|_| { | ||||
| Err(PyErr::new::<exc::OSError, _>( | Err(PyErr::new::<exc::OSError, _>( | ||||
| py, | py, | ||||
| "Dirstate error".to_string(), | "Dirstate error".to_string(), | ||||
| )) | )) | ||||
| }) | }) | ||||
| } | } | ||||
| def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> { | def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> { | ||||
| let p1 = extract_node_id(py, &p1)?; | let p1 = extract_node_id(py, &p1)?; | ||||
| let p2 = extract_node_id(py, &p2)?; | let p2 = extract_node_id(py, &p2)?; | ||||
| self.inner(py).borrow_mut() | self.inner(py).borrow_mut() | ||||
| .set_parents(&DirstateParents { p1, p2 }); | .set_parents(&DirstateParents { p1, p2 }); | ||||
| Ok(py.None()) | Ok(py.None()) | ||||
| } | } | ||||
| def read(&self, st: PyObject) -> PyResult<Option<PyObject>> { | def read(&self, st: PyObject) -> PyResult<Option<PyObject>> { | ||||
| match self.inner(py).borrow_mut() | match self.inner(py).borrow_mut() | ||||
| .read(st.extract::<PyBytes>(py)?.data(py)) | .read(st.extract::<PyBytes>(py)?.data(py)) | ||||
| { | { | ||||
| Ok(Some(parents)) => Ok(Some( | Ok(Some(parents)) => Ok(Some( | ||||
| (PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2)) | dirstate_parents_to_pytuple(py, parents) | ||||
| .to_py_object(py) | .into_object() | ||||
| .into_object(), | |||||
| )), | )), | ||||
| Ok(None) => Ok(Some(py.None())), | Ok(None) => Ok(Some(py.None())), | ||||
| Err(_) => Err(PyErr::new::<exc::OSError, _>( | Err(_) => Err(PyErr::new::<exc::OSError, _>( | ||||
| py, | py, | ||||
| "Dirstate error".to_string(), | "Dirstate error".to_string(), | ||||
| )), | )), | ||||
| } | } | ||||
| } | } | ||||
| py_shared_iterator!( | py_shared_iterator!( | ||||
| DirstateMapItemsIterator, | DirstateMapItemsIterator, | ||||
| UnsafePyLeaked<StateMapIter<'static>>, | UnsafePyLeaked<StateMapIter<'static>>, | ||||
| DirstateMap::translate_key_value, | DirstateMap::translate_key_value, | ||||
| Option<(PyBytes, PyObject)> | Option<(PyBytes, PyObject)> | ||||
| ); | ); | ||||
| fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<[u8; PARENT_SIZE]> { | fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<Node> { | ||||
| let bytes = obj.extract::<PyBytes>(py)?; | let bytes = obj.extract::<PyBytes>(py)?; | ||||
| match bytes.data(py).try_into() { | match bytes.data(py).try_into() { | ||||
| Ok(s) => Ok(s), | Ok(s) => Ok(s), | ||||
| Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())), | Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())), | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| for (path, copy_path) in copy_map { | for (path, copy_path) in copy_map { | ||||
| copymap.set_item( | copymap.set_item( | ||||
| py, | py, | ||||
| PyBytes::new(py, path.as_bytes()), | PyBytes::new(py, path.as_bytes()), | ||||
| PyBytes::new(py, copy_path.as_bytes()), | PyBytes::new(py, copy_path.as_bytes()), | ||||
| )?; | )?; | ||||
| } | } | ||||
| Ok( | Ok(dirstate_parents_to_pytuple(py, parents)) | ||||
| (PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2)) | |||||
| .to_py_object(py), | |||||
| ) | |||||
| } | } | ||||
| Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())), | Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())), | ||||
| } | } | ||||
| } | } | ||||
| fn pack_dirstate_wrapper( | fn pack_dirstate_wrapper( | ||||
| py: Python, | py: Python, | ||||
| dmap: PyDict, | dmap: PyDict, | ||||
| )?; | )?; | ||||
| let sys = PyModule::import(py, "sys")?; | let sys = PyModule::import(py, "sys")?; | ||||
| let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?; | let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?; | ||||
| sys_modules.set_item(py, dotted_name, &m)?; | sys_modules.set_item(py, dotted_name, &m)?; | ||||
| Ok(m) | Ok(m) | ||||
| } | } | ||||
| pub(crate) fn dirstate_parents_to_pytuple( | |||||
| py: Python, | |||||
| parents: &DirstateParents, | |||||
| ) -> PyTuple { | |||||
| let p1 = PyBytes::new(py, parents.p1.as_bytes()); | |||||
| let p2 = PyBytes::new(py, parents.p2.as_bytes()); | |||||
| (p1, p2).to_py_object(py) | |||||
| } | |||||