Skip to main content

nv_redfish/
power_equipment.rs

1// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Power equipment entities and collections.
17//!
18//! This module provides typed access to Redfish `PowerEquipment` and the
19//! power shelf resources exposed through its `PowerShelves` collection.
20
21use crate::core::NavProperty;
22use crate::schema::power_distribution::PowerDistribution as PowerDistributionSchema;
23use crate::schema::power_distribution_collection::PowerDistributionCollection as PowerDistributionCollectionSchema;
24use crate::schema::power_equipment::PowerEquipment as PowerEquipmentSchema;
25use crate::Error;
26use crate::NvBmc;
27use crate::Resource;
28use crate::ResourceSchema;
29use crate::ServiceRoot;
30use nv_redfish_core::Bmc;
31use std::marker::PhantomData;
32use std::sync::Arc;
33
34#[doc(inline)]
35pub use crate::schema::power_distribution::PowerEquipmentType;
36
37/// Power equipment service.
38///
39/// Provides access to root-level power distribution equipment collections.
40pub struct PowerEquipment<B: Bmc> {
41    bmc: NvBmc<B>,
42    data: Arc<PowerEquipmentSchema>,
43}
44
45impl<B: Bmc> PowerEquipment<B> {
46    /// Create a new power equipment handle.
47    pub(crate) async fn new(
48        bmc: &NvBmc<B>,
49        root: &ServiceRoot<B>,
50    ) -> Result<Option<Self>, Error<B>> {
51        let Some(nav) = &root.root.power_equipment else {
52            return Ok(None);
53        };
54
55        let data = nav.get(bmc.as_ref()).await.map_err(Error::Bmc)?;
56
57        Ok(Some(Self {
58            bmc: bmc.clone(),
59            data,
60        }))
61    }
62
63    /// Get the raw schema data for this power equipment service.
64    ///
65    /// Returns an `Arc` to the underlying schema, allowing cheap cloning
66    /// and sharing of the data.
67    #[must_use]
68    pub fn raw(&self) -> Arc<PowerEquipmentSchema> {
69        self.data.clone()
70    }
71
72    /// Get the power shelf collection.
73    ///
74    /// Returns `Ok(None)` when the service does not expose `PowerShelves`.
75    ///
76    /// # Errors
77    ///
78    /// Returns an error if retrieving the power shelf collection fails.
79    pub async fn power_shelves(&self) -> Result<Option<PowerShelfCollection<B>>, Error<B>> {
80        let Some(collection_ref) = &self.data.power_shelves else {
81            return Ok(None);
82        };
83
84        PowerShelfCollection::new(&self.bmc, collection_ref)
85            .await
86            .map(Some)
87    }
88}
89
90impl<B: Bmc> Resource for PowerEquipment<B> {
91    fn resource_ref(&self) -> &ResourceSchema {
92        &self.data.as_ref().base
93    }
94}
95
96/// Power shelf collection.
97///
98/// Provides functions to access `PowerShelves` members.
99pub struct PowerShelfCollection<B: Bmc> {
100    bmc: NvBmc<B>,
101    collection: Arc<PowerDistributionCollectionSchema>,
102}
103
104impl<B: Bmc> PowerShelfCollection<B> {
105    async fn new(
106        bmc: &NvBmc<B>,
107        nav: &NavProperty<PowerDistributionCollectionSchema>,
108    ) -> Result<Self, Error<B>> {
109        let collection = bmc.expand_property(nav).await?;
110        Ok(Self {
111            bmc: bmc.clone(),
112            collection,
113        })
114    }
115
116    /// List all power shelves available in this collection.
117    ///
118    /// # Errors
119    ///
120    /// Returns an error if fetching power shelf data fails.
121    pub async fn members(&self) -> Result<Vec<PowerShelf<B>>, Error<B>> {
122        let mut members = Vec::with_capacity(self.collection.members.len());
123        for member in &self.collection.members {
124            members.push(PowerShelf::new(&self.bmc, member).await?);
125        }
126
127        Ok(members)
128    }
129}
130
131/// Power shelf.
132///
133/// A power shelf is represented by the Redfish `PowerDistribution` schema with
134/// `EquipmentType` set to `PowerShelf`.
135pub struct PowerShelf<B: Bmc> {
136    data: Arc<PowerDistributionSchema>,
137    _marker: PhantomData<B>,
138}
139
140impl<B: Bmc> PowerShelf<B> {
141    async fn new(
142        bmc: &NvBmc<B>,
143        nav: &NavProperty<PowerDistributionSchema>,
144    ) -> Result<Self, Error<B>> {
145        let data = nav.get(bmc.as_ref()).await.map_err(Error::Bmc)?;
146        Ok(Self {
147            data,
148            _marker: PhantomData,
149        })
150    }
151
152    /// Get the raw `PowerDistribution` schema data for this power shelf.
153    ///
154    /// Returns an `Arc` to the underlying schema, allowing cheap cloning
155    /// and sharing of the data.
156    #[must_use]
157    pub fn raw(&self) -> Arc<PowerDistributionSchema> {
158        self.data.clone()
159    }
160}
161
162impl<B: Bmc> Resource for PowerShelf<B> {
163    fn resource_ref(&self) -> &ResourceSchema {
164        &self.data.as_ref().base
165    }
166}