trident/package/registry/
store_integration.rs1use crate::hash::ContentHash;
2use crate::store::{Codebase, Definition};
3
4use super::client::RegistryClient;
5use super::types::*;
6
7pub fn publish_codebase(
8 codebase: &Codebase,
9 client: &RegistryClient,
10 tags: &[String],
11) -> Result<Vec<PublishResult>, String> {
12 let names = codebase.list_names();
13 let mut results = Vec::new();
14
15 for (name, hash) in &names {
16 let def = match codebase.lookup_hash(hash) {
17 Some(d) => d,
18 None => continue,
19 };
20
21 let pub_def = PublishedDefinition {
22 hash: hash.to_hex(),
23 source: def.source.clone(),
24 module: def.module.clone(),
25 is_pub: def.is_pub,
26 params: def.params.clone(),
27 return_ty: def.return_ty.clone(),
28 dependencies: def.dependencies.iter().map(|h| h.to_hex()).collect(),
29 requires: def.requires.clone(),
30 ensures: def.ensures.clone(),
31 name: Some(name.to_string()),
32 tags: tags.to_vec(),
33 verified: false,
34 verification_cert: None,
35 };
36
37 match client.publish(&pub_def) {
38 Ok(result) => results.push(result),
39 Err(e) => {
40 return Err(format!("failed to publish '{}': {}", name, e));
41 }
42 }
43 }
44
45 Ok(results)
46}
47
48pub fn pull_into_codebase(
50 codebase: &mut Codebase,
51 client: &RegistryClient,
52 name_or_hash: &str,
53) -> Result<PullResult, String> {
54 let pull = if name_or_hash.len() == 64 && name_or_hash.chars().all(|c| c.is_ascii_hexdigit()) {
55 client.pull(name_or_hash)?
56 } else {
57 client.pull_by_name(name_or_hash)?
58 };
59
60 let hash = ContentHash::from_hex(&pull.hash)
61 .ok_or_else(|| "invalid hash in pull response".to_string())?;
62
63 if codebase.lookup_hash(&hash).is_some() {
64 return Ok(pull);
65 }
66
67 let deps: Vec<ContentHash> = pull
68 .dependencies
69 .iter()
70 .filter_map(|h| ContentHash::from_hex(h))
71 .collect();
72
73 let def = Definition {
74 source: pull.source.clone(),
75 module: pull.module.clone(),
76 is_pub: true,
77 params: pull.params.clone(),
78 return_ty: pull.return_ty.clone(),
79 dependencies: deps,
80 requires: pull.requires.clone(),
81 ensures: pull.ensures.clone(),
82 first_seen: crate::package::unix_timestamp(),
83 };
84
85 codebase.store_definition(hash, def);
86
87 if name_or_hash.len() != 64 || !name_or_hash.chars().all(|c| c.is_ascii_hexdigit()) {
88 codebase.bind_name(name_or_hash, hash);
89 }
90
91 codebase.save().map_err(|e| e.to_string())?;
92
93 Ok(pull)
94}