view rust/hg-core/src/dirstate_tree/owning.rs @ 49210:34decbaf4da3

node: manually implement Debug I got too irritated today with the default Debug implementation of hg::revlog::Node while playing with a new parser. This isn't quite what I wanted, but it wasn't much code and it at least gives you output that's easy to visually compare to a node.hex()ed identifier from the Python side of things. Sadly, this doesn't influence the output in lldb or the VSCode debugger extension that uses lldb under the covers, but it at least means debug prints are a little more useful. Differential Revision: https://phab.mercurial-scm.org/D12608
author Augie Fackler <augie@google.com>
date Thu, 05 May 2022 14:47:26 -0400
parents dd6b67d5c256
children 6cce0afc1454 e98fd81bb151
line wrap: on
line source

use crate::{DirstateError, DirstateParents};

use super::dirstate_map::DirstateMap;
use std::ops::Deref;

use ouroboros::self_referencing;

/// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it
/// borrows.
#[self_referencing]
pub struct OwningDirstateMap {
    on_disk: Box<dyn Deref<Target = [u8]> + Send>,
    #[borrows(on_disk)]
    #[covariant]
    map: DirstateMap<'this>,
}

impl OwningDirstateMap {
    pub fn new_empty<OnDisk>(on_disk: OnDisk) -> Self
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);

        OwningDirstateMapBuilder {
            on_disk,
            map_builder: |bytes| DirstateMap::empty(&bytes),
        }
        .build()
    }

    pub fn new_v1<OnDisk>(
        on_disk: OnDisk,
    ) -> Result<(Self, DirstateParents), DirstateError>
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);
        let mut parents = DirstateParents::NULL;

        Ok((
            OwningDirstateMapTryBuilder {
                on_disk,
                map_builder: |bytes| {
                    DirstateMap::new_v1(&bytes).map(|(dmap, p)| {
                        parents = p.unwrap_or(DirstateParents::NULL);
                        dmap
                    })
                },
            }
            .try_build()?,
            parents,
        ))
    }

    pub fn new_v2<OnDisk>(
        on_disk: OnDisk,
        data_size: usize,
        metadata: &[u8],
    ) -> Result<Self, DirstateError>
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);

        OwningDirstateMapTryBuilder {
            on_disk,
            map_builder: |bytes| {
                DirstateMap::new_v2(&bytes, data_size, metadata)
            },
        }
        .try_build()
    }

    pub fn with_dmap_mut<R>(
        &mut self,
        f: impl FnOnce(&mut DirstateMap) -> R,
    ) -> R {
        self.with_map_mut(f)
    }

    pub fn get_map(&self) -> &DirstateMap {
        self.borrow_map()
    }

    pub fn on_disk(&self) -> &[u8] {
        self.borrow_on_disk()
    }
}