veryl_metadata/
metadata_output.rs1use crate::lockfile::{Lock, LockSource};
2use crate::metadata::Metadata;
3use crate::metadata_error::MetadataError;
4use semver::Version;
5use serde::Serialize;
6use std::collections::{BTreeMap, HashMap};
7use std::path::PathBuf;
8
9#[derive(Clone, Debug, Serialize, PartialEq)]
10pub struct MetadataOutputV2 {
11 pub format_version: usize,
12 pub root: MetadataProjectV2,
13 pub dependencies: Vec<MetadataDependencyV2>,
14}
15
16#[derive(Clone, Debug, Serialize, PartialEq)]
17pub struct MetadataProjectV2 {
18 pub name: String,
19 pub version: Option<Version>,
20 pub local_path: PathBuf,
21 pub metadata: BTreeMap<String, toml::Value>,
22}
23
24#[derive(Clone, Debug, Serialize, PartialEq)]
25pub struct MetadataDependencyV2 {
26 pub id: String,
27 pub name: String,
28 pub project: String,
29 pub source: MetadataSourceV2,
30 pub local_path: PathBuf,
31 pub metadata: BTreeMap<String, toml::Value>,
32 pub dependencies: Vec<String>,
33}
34
35#[derive(Clone, Debug, Serialize, PartialEq)]
36#[serde(tag = "kind", rename_all = "snake_case")]
37pub enum MetadataSourceV2 {
38 Path {
39 path: PathBuf,
40 },
41 Repository {
42 url: String,
43 project: String,
44 version: Version,
45 revision: String,
46 path: PathBuf,
47 },
48}
49
50impl MetadataOutputV2 {
51 pub fn from_metadata(metadata: &Metadata) -> Result<Self, MetadataError> {
52 let project_path = metadata.project_path();
53 let locks = metadata.lockfile.projects();
54 let dependency_ids = locks
55 .iter()
56 .map(|lock| (lock.source.clone(), format!("dep:{}", lock.name)))
57 .collect::<HashMap<_, _>>();
58 let mut dependencies = locks
59 .iter()
60 .map(|lock| MetadataDependencyV2::from_lock(lock, metadata, &dependency_ids))
61 .collect::<Result<Vec<_>, _>>()?;
62 dependencies.sort_by(|x, y| x.id.cmp(&y.id));
63
64 Ok(Self {
65 format_version: 2,
66 root: MetadataProjectV2 {
67 name: metadata.project.name.clone(),
68 version: metadata.project.version.clone(),
69 local_path: project_path,
70 metadata: metadata.metadata.clone().into_iter().collect(),
71 },
72 dependencies,
73 })
74 }
75}
76
77impl MetadataDependencyV2 {
78 fn from_lock(
79 lock: &Lock,
80 root_metadata: &Metadata,
81 dependency_ids: &HashMap<LockSource, String>,
82 ) -> Result<Self, MetadataError> {
83 let source = MetadataSourceV2::from_lock_source(&lock.source);
84 let metadata = root_metadata.lockfile.get_metadata(&lock.source)?;
85 let mut dependencies = lock
86 .dependencies
87 .iter()
88 .map(|dependency| {
89 dependency_ids
90 .get(&dependency.source)
91 .cloned()
92 .unwrap_or_else(|| format!("dep:{}", dependency.name))
93 })
94 .collect::<Vec<_>>();
95 dependencies.sort();
96
97 Ok(Self {
98 id: format!("dep:{}", lock.name),
100 name: lock.name.clone(),
101 project: metadata.project.name.clone(),
102 local_path: metadata.project_path(),
103 metadata: metadata.metadata.into_iter().collect(),
104 source,
105 dependencies,
106 })
107 }
108}
109
110impl MetadataSourceV2 {
111 fn from_lock_source(source: &LockSource) -> Self {
112 match source {
113 LockSource::Path(path) => Self::Path { path: path.clone() },
114 LockSource::Repository(repository) => Self::Repository {
115 url: repository.url.to_string(),
116 project: repository.project.clone(),
117 version: repository.version.clone(),
118 revision: repository.revision.clone(),
119 path: repository.path.clone(),
120 },
121 }
122 }
123}