pyoxidizerlib/starlark/
python_package_distribution_resource.rs1use {
6 super::python_resource::ResourceCollectionContext,
7 python_packaging::{
8 resource::{PythonPackageDistributionResource, PythonResource},
9 resource_collection::PythonResourceAddCollectionContext,
10 },
11 starlark::values::{
12 error::{RuntimeError, UnsupportedOperation, ValueError},
13 {Mutable, TypedValue, Value, ValueResult},
14 },
15 std::sync::{Arc, Mutex, MutexGuard},
16};
17
18#[derive(Debug)]
19pub struct PythonPackageDistributionResourceWrapper {
20 pub r: PythonPackageDistributionResource,
21 pub add_context: Option<PythonResourceAddCollectionContext>,
22}
23
24#[derive(Debug, Clone)]
26pub struct PythonPackageDistributionResourceValue {
27 inner: Arc<Mutex<PythonPackageDistributionResourceWrapper>>,
28 package: String,
29 name: String,
30}
31
32impl PythonPackageDistributionResourceValue {
33 pub fn new(resource: PythonPackageDistributionResource) -> Self {
34 let package = resource.package.clone();
35 let name = resource.name.clone();
36
37 Self {
38 inner: Arc::new(Mutex::new(PythonPackageDistributionResourceWrapper {
39 r: resource,
40 add_context: None,
41 })),
42 package,
43 name,
44 }
45 }
46
47 pub fn inner(
48 &self,
49 label: &str,
50 ) -> Result<MutexGuard<PythonPackageDistributionResourceWrapper>, ValueError> {
51 self.inner.try_lock().map_err(|e| {
52 ValueError::Runtime(RuntimeError {
53 code: "PYTHON_PACKAGE_DISTRIBUTION_RESOURCE",
54 message: format!("failed to acquire lock: {}", e),
55 label: label.to_string(),
56 })
57 })
58 }
59}
60
61impl ResourceCollectionContext for PythonPackageDistributionResourceValue {
62 fn add_collection_context(
63 &self,
64 ) -> Result<Option<PythonResourceAddCollectionContext>, ValueError> {
65 Ok(self
66 .inner("PythonPackageDistributionResource.add_collection_context()")?
67 .add_context
68 .clone())
69 }
70
71 fn replace_add_collection_context(
72 &mut self,
73 context: PythonResourceAddCollectionContext,
74 ) -> Result<Option<PythonResourceAddCollectionContext>, ValueError> {
75 Ok(self
76 .inner("PythonPackageDistributionResource.replace_add_collection_context()")?
77 .add_context
78 .replace(context))
79 }
80
81 fn as_python_resource(&self) -> Result<PythonResource<'_>, ValueError> {
82 Ok(PythonResource::from(
83 self.inner("PythonPackageDistributionResource.as_python_resource()")?
84 .r
85 .clone(),
86 ))
87 }
88}
89
90impl TypedValue for PythonPackageDistributionResourceValue {
91 type Holder = Mutable<PythonPackageDistributionResourceValue>;
92 const TYPE: &'static str = "PythonPackageDistributionResource";
93
94 fn values_for_descendant_check_and_freeze(&self) -> Box<dyn Iterator<Item = Value>> {
95 Box::new(std::iter::empty())
96 }
97
98 fn to_str(&self) -> String {
99 format!(
100 "{}<package={}, name={}>",
101 Self::TYPE,
102 self.package,
103 self.name
104 )
105 }
106
107 fn to_repr(&self) -> String {
108 self.to_str()
109 }
110
111 fn to_bool(&self) -> bool {
112 true
113 }
114
115 fn get_attr(&self, attribute: &str) -> ValueResult {
116 let inner = self.inner(&format!("PythonPackageDistributionResource.{}", attribute))?;
117
118 let v = match attribute {
119 "is_stdlib" => Value::from(false),
120 "package" => Value::new(inner.r.package.clone()),
121 "name" => Value::new(inner.r.name.clone()),
122 attr => {
124 drop(inner);
125
126 return if self.add_collection_context_attrs().contains(&attr) {
127 self.get_attr_add_collection_context(attr)
128 } else {
129 Err(ValueError::OperationNotSupported {
130 op: UnsupportedOperation::GetAttr(attr.to_string()),
131 left: Self::TYPE.to_string(),
132 right: None,
133 })
134 };
135 }
136 };
137
138 Ok(v)
139 }
140
141 fn has_attr(&self, attribute: &str) -> Result<bool, ValueError> {
142 Ok(match attribute {
143 "is_stdlib" => true,
144 "package" => true,
145 "name" => true,
146 attr => self.add_collection_context_attrs().contains(&attr),
148 })
149 }
150
151 fn set_attr(&mut self, attribute: &str, value: Value) -> Result<(), ValueError> {
152 if self.add_collection_context_attrs().contains(&attribute) {
153 self.set_attr_add_collection_context(attribute, value)
154 } else {
155 Err(ValueError::OperationNotSupported {
156 op: UnsupportedOperation::SetAttr(attribute.to_string()),
157 left: Self::TYPE.to_owned(),
158 right: None,
159 })
160 }
161 }
162}