1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#![allow(missing_docs)]
use std::{rc::Rc, sync::Arc};

use parking_lot::lock_api::{ArcRwLockReadGuard, ArcRwLockWriteGuard};

use crate::{easy, Easy, EasyArc, EasyShared, Repository};

impl From<Repository> for Easy {
    fn from(repo: Repository) -> Self {
        Easy {
            repo: Rc::new(repo),
            state: Default::default(),
        }
    }
}

impl From<Repository> for EasyArc {
    fn from(repo: Repository) -> Self {
        EasyArc {
            repo: Arc::new(repo),
            state: Default::default(),
        }
    }
}

impl From<Repository> for crate::EasyArcExclusive {
    fn from(repo: Repository) -> Self {
        crate::EasyArcExclusive {
            repo: Arc::new(parking_lot::RwLock::new(repo)),
            state: Default::default(),
        }
    }
}

impl Repository {
    pub fn to_easy(&self) -> EasyShared<'_> {
        EasyShared {
            repo: self,
            state: Default::default(),
        }
    }
    pub fn into_easy(self) -> Easy {
        self.into()
    }

    pub fn into_easy_arc(self) -> EasyArc {
        self.into()
    }

    pub fn into_easy_arc_exclusive(self) -> crate::EasyArcExclusive {
        self.into()
    }
}

impl<'repo> easy::Access for EasyShared<'repo> {
    type RepoRef = &'repo Repository;
    type RepoRefMut = &'repo mut Repository;

    fn repo(&self) -> Result<Self::RepoRef, easy::borrow::repo::Error> {
        Ok(self.repo)
    }

    fn repo_mut(&self) -> Result<Self::RepoRefMut, easy::borrow::repo::Error> {
        Err(easy::borrow::repo::Error)
    }

    fn state(&self) -> &easy::State {
        &self.state
    }
}

impl easy::Access for Easy {
    type RepoRef = Rc<Repository>; // TODO: this could be a reference with GATs
    type RepoRefMut = &'static mut Repository; // this is a lie

    fn repo(&self) -> Result<Self::RepoRef, easy::borrow::repo::Error> {
        Ok(self.repo.clone())
    }

    /// TODO: With GATs, this can return an actual RefMut<'a, _> so mutability is possible in single-threaded mode.
    fn repo_mut(&self) -> Result<Self::RepoRefMut, easy::borrow::repo::Error> {
        Err(easy::borrow::repo::Error)
    }

    fn state(&self) -> &easy::State {
        &self.state
    }
}

impl easy::Access for EasyArc {
    type RepoRef = Arc<Repository>;
    type RepoRefMut = &'static mut Repository; // this is a lie

    fn repo(&self) -> Result<Self::RepoRef, easy::borrow::repo::Error> {
        Ok(self.repo.clone())
    }
    fn repo_mut(&self) -> Result<Self::RepoRefMut, easy::borrow::repo::Error> {
        Err(easy::borrow::repo::Error)
    }
    fn state(&self) -> &easy::State {
        &self.state
    }
}

impl easy::Access for crate::EasyArcExclusive {
    type RepoRef = ArcRwLockReadGuard<parking_lot::RawRwLock, Repository>;
    type RepoRefMut = ArcRwLockWriteGuard<parking_lot::RawRwLock, Repository>;

    fn repo(&self) -> Result<Self::RepoRef, easy::borrow::repo::Error> {
        Ok(self.repo.read_arc())
    }
    fn repo_mut(&self) -> Result<Self::RepoRefMut, easy::borrow::repo::Error> {
        Ok(self.repo.write_arc())
    }
    fn state(&self) -> &easy::State {
        &self.state
    }
}