13 use cpython::{ |
13 use cpython::{ |
14 exc, PyBytes, PyDict, PyErr, PyInt, PyModule, PyResult, PyTuple, Python, |
14 exc, PyBytes, PyDict, PyErr, PyInt, PyModule, PyResult, PyTuple, Python, |
15 PythonObject, ToPyObject, |
15 PythonObject, ToPyObject, |
16 }; |
16 }; |
17 use hg::{ |
17 use hg::{ |
18 pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry, |
18 pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, |
19 DirstatePackError, DirstateParents, DirstateParseError, PARENT_SIZE, |
19 DirstatePackError, DirstateParents, DirstateParseError, PARENT_SIZE, |
20 }; |
20 }; |
21 use std::collections::HashMap; |
21 use std::collections::HashMap; |
22 use std::convert::TryInto; |
22 use std::convert::TryInto; |
23 |
23 |
24 use libc::c_char; |
24 use crate::dirstate::{extract_dirstate, make_dirstate_tuple}; |
25 |
|
26 use crate::dirstate::{decapsule_make_dirstate_tuple, extract_dirstate}; |
|
27 use std::time::Duration; |
25 use std::time::Duration; |
28 |
26 |
29 fn parse_dirstate_wrapper( |
27 fn parse_dirstate_wrapper( |
30 py: Python, |
28 py: Python, |
31 dmap: PyDict, |
29 dmap: PyDict, |
35 let mut dirstate_map = HashMap::new(); |
33 let mut dirstate_map = HashMap::new(); |
36 let mut copies = HashMap::new(); |
34 let mut copies = HashMap::new(); |
37 |
35 |
38 match parse_dirstate(&mut dirstate_map, &mut copies, st.data(py)) { |
36 match parse_dirstate(&mut dirstate_map, &mut copies, st.data(py)) { |
39 Ok(parents) => { |
37 Ok(parents) => { |
40 for (filename, entry) in dirstate_map { |
38 for (filename, entry) in &dirstate_map { |
41 // Explicitly go through u8 first, then cast to |
|
42 // platform-specific `c_char` because Into<u8> has a specific |
|
43 // implementation while `as c_char` would just do a naive enum |
|
44 // cast. |
|
45 let state: u8 = entry.state.into(); |
|
46 |
|
47 dmap.set_item( |
39 dmap.set_item( |
48 py, |
40 py, |
49 PyBytes::new(py, filename.as_ref()), |
41 PyBytes::new(py, filename.as_ref()), |
50 decapsule_make_dirstate_tuple(py)?( |
42 make_dirstate_tuple(py, entry)?, |
51 state as c_char, |
|
52 entry.mode, |
|
53 entry.size, |
|
54 entry.mtime, |
|
55 ), |
|
56 )?; |
43 )?; |
57 } |
44 } |
58 for (path, copy_path) in copies { |
45 for (path, copy_path) in copies { |
59 copymap.set_item( |
46 copymap.set_item( |
60 py, |
47 py, |
125 p2: p2.try_into().unwrap(), |
112 p2: p2.try_into().unwrap(), |
126 }, |
113 }, |
127 Duration::from_secs(now.as_object().extract::<u64>(py)?), |
114 Duration::from_secs(now.as_object().extract::<u64>(py)?), |
128 ) { |
115 ) { |
129 Ok(packed) => { |
116 Ok(packed) => { |
130 for ( |
117 for (filename, entry) in &dirstate_map { |
131 filename, |
|
132 DirstateEntry { |
|
133 state, |
|
134 mode, |
|
135 size, |
|
136 mtime, |
|
137 }, |
|
138 ) in dirstate_map |
|
139 { |
|
140 // Explicitly go through u8 first, then cast to |
|
141 // platform-specific `c_char` because Into<u8> has a specific |
|
142 // implementation while `as c_char` would just do a naive enum |
|
143 // cast. |
|
144 let state: u8 = state.into(); |
|
145 dmap.set_item( |
118 dmap.set_item( |
146 py, |
119 py, |
147 PyBytes::new(py, filename.as_ref()), |
120 PyBytes::new(py, filename.as_ref()), |
148 decapsule_make_dirstate_tuple(py)?( |
121 make_dirstate_tuple(py, entry)?, |
149 state as c_char, |
|
150 mode, |
|
151 size, |
|
152 mtime, |
|
153 ), |
|
154 )?; |
122 )?; |
155 } |
123 } |
156 Ok(PyBytes::new(py, &packed)) |
124 Ok(PyBytes::new(py, &packed)) |
157 } |
125 } |
158 Err(error) => Err(PyErr::new::<exc::ValueError, _>( |
126 Err(error) => Err(PyErr::new::<exc::ValueError, _>( |