summaryrefslogtreecommitdiffstats
path: root/src/filestore/util.rs
blob: 2fc14833050c29f67e6c436e9c96fb78aaaac0c4 (plain)
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
//
// Copyright (c) 2020-2021 science+computing ag and other contributors
//
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//

//! Module containing utilities for the filestore implementation
//!

use std::collections::BTreeMap;

use anyhow::anyhow;
use anyhow::Result;
use indicatif::ProgressBar;
use resiter::AndThen;

use crate::filestore::path::*;
use crate::filestore::Artifact;

/// The actual filestore implementation
///
/// Because the "staging" filestore and the "release" filestore function the same underneath, we
/// provide this type as the implementation.
///
/// It can then be wrapped into the actual interface of this module with specialized functionality.
pub struct FileStoreImpl {
    pub(in crate::filestore) root: StoreRoot,
    store: BTreeMap<ArtifactPath, Artifact>,
}

impl FileStoreImpl {
    /// Loads the passed path recursively into a Path => Artifact mapping
    pub fn load(root: StoreRoot, progress: ProgressBar) -> Result<Self> {
        let store = root
            .find_artifacts_recursive()
            .and_then_ok(|artifact_path| {
                progress.tick();
                Artifact::load(&root, artifact_path.clone()).map(|a| (artifact_path, a))
            })
            .collect::<Result<BTreeMap<ArtifactPath, Artifact>>>()?;

        Ok(FileStoreImpl { root, store })
    }

    pub fn root_path(&self) -> &StoreRoot {
        &self.root
    }

    pub fn get(&self, artifact_path: &ArtifactPath) -> Option<&Artifact> {
        self.store.get(artifact_path)
    }

    pub(in crate::filestore) fn load_from_path(
        &mut self,
        artifact_path: &ArtifactPath,
    ) -> Result<&Artifact> {
        if self.store.get(&artifact_path).is_some() {
            Err(anyhow!("Entry exists: {}", artifact_path.display()))
        } else {
            Ok(self
                .store
                .entry(artifact_path.clone())
                .or_insert(Artifact::load(&self.root, artifact_path.clone())?))
        }
    }
}