1use std::path::{Path, PathBuf};
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "lowercase")]
10pub enum SourceScope {
11 User,
13 Project,
15 #[default]
17 Temporary,
18}
19
20#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[serde(rename_all = "kebab-case")]
23pub enum SourceOrigin {
24 Package,
26 #[default]
28 TopLevel,
29}
30
31#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase")]
34pub struct PathMetadata {
35 pub source: String,
37 pub scope: SourceScope,
39 pub origin: SourceOrigin,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
43 pub base_dir: Option<PathBuf>,
44}
45
46#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub struct SourceInfo {
50 pub path: PathBuf,
52 pub source: String,
54 pub scope: SourceScope,
56 pub origin: SourceOrigin,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub base_dir: Option<PathBuf>,
61}
62
63impl SourceInfo {
64 #[must_use]
66 pub fn from_metadata(path: &Path, metadata: &PathMetadata) -> Self {
67 Self {
68 path: path.to_path_buf(),
69 source: metadata.source.clone(),
70 scope: metadata.scope,
71 origin: metadata.origin,
72 base_dir: metadata.base_dir.clone(),
73 }
74 }
75
76 #[must_use]
78 pub fn synthetic(
79 path: &Path,
80 source: &str,
81 scope: Option<SourceScope>,
82 base_dir: Option<PathBuf>,
83 ) -> Self {
84 Self {
85 path: path.to_path_buf(),
86 source: source.to_owned(),
87 scope: scope.unwrap_or_default(),
88 origin: SourceOrigin::TopLevel,
89 base_dir,
90 }
91 }
92}