Mercurial > public > mercurial-scm > hg
comparison rust/hg-cpython/src/parsers.rs @ 43208:1ca3823aeefd
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()
There are a couple of safety issues. First, the returned function pointer
must be unsafe. Second, its return value must be a raw pointer (i.e.
python27_sys::PyObject), not a cpython::PyObject. The wrapper function will
address these issues.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 13 Oct 2019 16:55:17 +0900 |
parents | 7a01778bc7b7 |
children | ce088b38f92b |
comparison
equal
deleted
inserted
replaced
43207:4aa9f3a1c1df | 43208:1ca3823aeefd |
---|---|
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, _>( |