pyoxidizerlib/starlark/
python_package_resource.rs1use {
6 super::python_resource::ResourceCollectionContext,
7 python_packaging::{
8 resource::{PythonPackageResource, 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 PythonPackageResourceWrapper {
20 pub r: PythonPackageResource,
21 pub add_context: Option<PythonResourceAddCollectionContext>,
22}
23
24#[derive(Debug, Clone)]
26pub struct PythonPackageResourceValue {
27 inner: Arc<Mutex<PythonPackageResourceWrapper>>,
28 leaf_package: String,
29 relative_name: String,
30}
31
32impl PythonPackageResourceValue {
33 pub fn new(resource: PythonPackageResource) -> Self {
34 let leaf_package = resource.leaf_package.clone();
35 let relative_name = resource.relative_name.clone();
36
37 Self {
38 inner: Arc::new(Mutex::new(PythonPackageResourceWrapper {
39 r: resource,
40 add_context: None,
41 })),
42 leaf_package,
43 relative_name,
44 }
45 }
46
47 pub fn inner(
48 &self,
49 label: &str,
50 ) -> Result<MutexGuard<PythonPackageResourceWrapper>, ValueError> {
51 self.inner.try_lock().map_err(|e| {
52 ValueError::Runtime(RuntimeError {
53 code: "PYTHON_PACKAGE_RESOURCE",
54 message: format!("failed to acquire lock: {}", e),
55 label: label.to_string(),
56 })
57 })
58 }
59}
60
61impl ResourceCollectionContext for PythonPackageResourceValue {
62 fn add_collection_context(
63 &self,
64 ) -> Result<Option<PythonResourceAddCollectionContext>, ValueError> {
65 Ok(self
66 .inner("PythonPackageResource.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("PythonPackageResource.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("PythonPackageResource.as_python_resource()")?
84 .r
85 .clone(),
86 ))
87 }
88}
89
90impl TypedValue for PythonPackageResourceValue {
91 type Holder = Mutable<PythonPackageResourceValue>;
92 const TYPE: &'static str = "PythonPackageResource";
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.leaf_package,
103 self.relative_name
104 )
105 }
106
107 fn to_repr(&self) -> String {
108 self.to_str()
109 }
110
111 fn get_attr(&self, attribute: &str) -> ValueResult {
112 let inner = self.inner(&format!("PythonPackageResource.{}", attribute))?;
113
114 let v = match attribute {
115 "is_stdlib" => Value::from(inner.r.is_stdlib),
116 "package" => Value::new(inner.r.leaf_package.clone()),
117 "name" => Value::new(inner.r.relative_name.clone()),
118 attr => {
120 drop(inner);
121
122 return if self.add_collection_context_attrs().contains(&attr) {
123 self.get_attr_add_collection_context(attr)
124 } else {
125 Err(ValueError::OperationNotSupported {
126 op: UnsupportedOperation::GetAttr(attr.to_string()),
127 left: Self::TYPE.to_string(),
128 right: None,
129 })
130 };
131 }
132 };
133
134 Ok(v)
135 }
136
137 fn has_attr(&self, attribute: &str) -> Result<bool, ValueError> {
138 Ok(match attribute {
139 "is_stdlib" => true,
140 "package" => true,
141 "name" => true,
142 attr => self.add_collection_context_attrs().contains(&attr),
144 })
145 }
146
147 fn set_attr(&mut self, attribute: &str, value: Value) -> Result<(), ValueError> {
148 if self.add_collection_context_attrs().contains(&attribute) {
149 self.set_attr_add_collection_context(attribute, value)
150 } else {
151 Err(ValueError::OperationNotSupported {
152 op: UnsupportedOperation::SetAttr(attribute.to_string()),
153 left: Self::TYPE.to_owned(),
154 right: None,
155 })
156 }
157 }
158}