comparison rust/hg-core/src/dirstate/entry.rs @ 49100:38e5bb1425dd

rust-dirstate: introduce intermediate struct for dirstate-v2 data This is passed often as a long tuple that is not easy to know the form of, so we refactor everything in this struct. This also renames `wdir_tracked` to follow the Python `wc_tracked`, even though the on-disk format uses `WDIR_TRACKED`. I think a single naming scheme is better, but we can't easily break the Python impl now because of extensions, so this is low-effort enough and facilitates grepping. Differential Revision: https://phab.mercurial-scm.org/D12498
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 23 Mar 2022 17:38:59 +0100
parents 791430b0b2d2
children dd0430434ce9
comparison
equal deleted inserted replaced
49099:ed3ef8dacf02 49100:38e5bb1425dd
246 pub const SIZE_FROM_OTHER_PARENT: i32 = -2; 246 pub const SIZE_FROM_OTHER_PARENT: i32 = -2;
247 /// A special value used for internal representation of special case in 247 /// A special value used for internal representation of special case in
248 /// dirstate v1 format. 248 /// dirstate v1 format.
249 pub const SIZE_NON_NORMAL: i32 = -1; 249 pub const SIZE_NON_NORMAL: i32 = -1;
250 250
251 #[derive(Debug, Default, Copy, Clone)]
252 pub struct DirstateV2Data {
253 pub wc_tracked: bool,
254 pub p1_tracked: bool,
255 pub p2_info: bool,
256 pub mode_size: Option<(u32, u32)>,
257 pub mtime: Option<TruncatedTimestamp>,
258 pub fallback_exec: Option<bool>,
259 pub fallback_symlink: Option<bool>,
260 }
261
251 impl DirstateEntry { 262 impl DirstateEntry {
252 pub fn from_v2_data( 263 pub fn from_v2_data(v2_data: DirstateV2Data) -> Self {
253 wdir_tracked: bool, 264 let DirstateV2Data {
254 p1_tracked: bool, 265 wc_tracked,
255 p2_info: bool, 266 p1_tracked,
256 mode_size: Option<(u32, u32)>, 267 p2_info,
257 mtime: Option<TruncatedTimestamp>, 268 mode_size,
258 fallback_exec: Option<bool>, 269 mtime,
259 fallback_symlink: Option<bool>, 270 fallback_exec,
260 ) -> Self { 271 fallback_symlink,
272 } = v2_data;
261 if let Some((mode, size)) = mode_size { 273 if let Some((mode, size)) = mode_size {
262 // TODO: return an error for out of range values? 274 // TODO: return an error for out of range values?
263 assert!(mode & !RANGE_MASK_31BIT == 0); 275 assert!(mode & !RANGE_MASK_31BIT == 0);
264 assert!(size & !RANGE_MASK_31BIT == 0); 276 assert!(size & !RANGE_MASK_31BIT == 0);
265 } 277 }
266 let mut flags = Flags::empty(); 278 let mut flags = Flags::empty();
267 flags.set(Flags::WDIR_TRACKED, wdir_tracked); 279 flags.set(Flags::WDIR_TRACKED, wc_tracked);
268 flags.set(Flags::P1_TRACKED, p1_tracked); 280 flags.set(Flags::P1_TRACKED, p1_tracked);
269 flags.set(Flags::P2_INFO, p2_info); 281 flags.set(Flags::P2_INFO, p2_info);
270 if let Some(exec) = fallback_exec { 282 if let Some(exec) = fallback_exec {
271 flags.insert(Flags::HAS_FALLBACK_EXEC); 283 flags.insert(Flags::HAS_FALLBACK_EXEC);
272 if exec { 284 if exec {
366 pub fn new_removed(size: i32) -> Self { 378 pub fn new_removed(size: i32) -> Self {
367 Self::from_v1_data(EntryState::Removed, 0, size, 0) 379 Self::from_v1_data(EntryState::Removed, 0, size, 0)
368 } 380 }
369 381
370 pub fn new_tracked() -> Self { 382 pub fn new_tracked() -> Self {
371 Self::from_v2_data(true, false, false, None, None, None, None) 383 let data = DirstateV2Data {
384 wc_tracked: true,
385 ..Default::default()
386 };
387 Self::from_v2_data(data)
372 } 388 }
373 389
374 pub fn tracked(&self) -> bool { 390 pub fn tracked(&self) -> bool {
375 self.flags.contains(Flags::WDIR_TRACKED) 391 self.flags.contains(Flags::WDIR_TRACKED)
376 } 392 }
411 self.flags.intersects( 427 self.flags.intersects(
412 Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO, 428 Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO,
413 ) 429 )
414 } 430 }
415 431
416 /// Returns `(wdir_tracked, p1_tracked, p2_info, mode_size, mtime)` 432 pub(crate) fn v2_data(&self) -> DirstateV2Data {
417 pub(crate) fn v2_data(
418 &self,
419 ) -> (
420 bool,
421 bool,
422 bool,
423 Option<(u32, u32)>,
424 Option<TruncatedTimestamp>,
425 Option<bool>,
426 Option<bool>,
427 ) {
428 if !self.any_tracked() { 433 if !self.any_tracked() {
429 // TODO: return an Option instead? 434 // TODO: return an Option instead?
430 panic!("Accessing v2_data of an untracked DirstateEntry") 435 panic!("Accessing v2_data of an untracked DirstateEntry")
431 } 436 }
432 let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED); 437 let wc_tracked = self.flags.contains(Flags::WDIR_TRACKED);
433 let p1_tracked = self.flags.contains(Flags::P1_TRACKED); 438 let p1_tracked = self.flags.contains(Flags::P1_TRACKED);
434 let p2_info = self.flags.contains(Flags::P2_INFO); 439 let p2_info = self.flags.contains(Flags::P2_INFO);
435 let mode_size = self.mode_size; 440 let mode_size = self.mode_size;
436 let mtime = self.mtime; 441 let mtime = self.mtime;
437 ( 442 DirstateV2Data {
438 wdir_tracked, 443 wc_tracked,
439 p1_tracked, 444 p1_tracked,
440 p2_info, 445 p2_info,
441 mode_size, 446 mode_size,
442 mtime, 447 mtime,
443 self.get_fallback_exec(), 448 fallback_exec: self.get_fallback_exec(),
444 self.get_fallback_symlink(), 449 fallback_symlink: self.get_fallback_symlink(),
445 ) 450 }
446 } 451 }
447 452
448 fn v1_state(&self) -> EntryState { 453 fn v1_state(&self) -> EntryState {
449 if !self.any_tracked() { 454 if !self.any_tracked() {
450 // TODO: return an Option instead? 455 // TODO: return an Option instead?