Skip to main content

nv_redfish/
resource.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025 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//! Redfish resource
17
18use crate::core::EntityTypeRef as _;
19use crate::core::ODataId;
20use crate::ResourceSchema;
21use tagged_types::TaggedType;
22
23#[cfg(feature = "oem")]
24use crate::oem::OemIdentifier;
25#[cfg(feature = "resource-status")]
26use crate::ResourceStatusSchema;
27#[cfg(feature = "resource-status")]
28use std::convert::identity;
29
30#[doc(inline)]
31#[cfg(feature = "resource-status")]
32pub use crate::schema::redfish::resource::Health;
33
34#[doc(inline)]
35#[cfg(feature = "resource-status")]
36pub use crate::schema::redfish::resource::State;
37
38#[doc(inline)]
39#[cfg(feature = "computer-systems")]
40pub use crate::schema::redfish::resource::PowerState;
41
42/// Redfish resource identifier.
43pub type ResourceId = TaggedType<String, ResourceIdTag>;
44/// Reference to Redfish resource identifier.
45pub type ResourceIdRef<'a> = TaggedType<&'a str, ResourceIdTag>;
46#[doc(hidden)]
47#[derive(tagged_types::Tag)]
48#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
49#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
50#[capability(inner_access, cloned)]
51pub enum ResourceIdTag {}
52
53/// Redfish resource name.
54pub type ResourceName = TaggedType<String, ResourceNameTag>;
55/// Reference to Redfish resource name.
56pub type ResourceNameRef<'a> = TaggedType<&'a str, ResourceNameTag>;
57#[doc(hidden)]
58#[derive(tagged_types::Tag)]
59#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
60#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
61#[capability(inner_access, cloned)]
62pub enum ResourceNameTag {}
63
64/// Redfish resource description.
65pub type ResourceDescription = TaggedType<String, ResourceDescriptionTag>;
66/// Reference to Redfish resource description.
67pub type ResourceDescriptionRef<'a> = TaggedType<&'a str, ResourceDescriptionTag>;
68#[doc(hidden)]
69#[derive(tagged_types::Tag)]
70#[implement(Clone)]
71#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
72#[capability(inner_access, cloned)]
73pub enum ResourceDescriptionTag {}
74
75/// Represents Redfish Resource base type.
76pub trait Resource {
77    /// Required function. Must be implemented for Redfish resources.
78    fn resource_ref(&self) -> &ResourceSchema;
79
80    /// Identifier of the resource.
81    fn id(&self) -> ResourceIdRef<'_> {
82        ResourceIdRef::new(&self.resource_ref().id)
83    }
84
85    /// Name of the resource.
86    fn name(&self) -> ResourceNameRef<'_> {
87        ResourceNameRef::new(&self.resource_ref().name)
88    }
89
90    /// Description of the resource.
91    fn description(&self) -> Option<ResourceDescriptionRef<'_>> {
92        self.resource_ref()
93            .description
94            .as_ref()
95            .and_then(Option::as_deref)
96            .map(ResourceDescriptionRef::new)
97    }
98
99    /// OEM identifier if present in the resource.
100    #[cfg(feature = "oem")]
101    fn oem_id(&self) -> Option<OemIdentifier<&str>> {
102        oem_id_from_resource(self.resource_ref()).map(OemIdentifier::new)
103    }
104
105    /// OData identifier of the resource.
106    fn odata_id(&self) -> &ODataId {
107        self.resource_ref().odata_id()
108    }
109}
110
111#[cfg(feature = "oem")]
112pub(crate) fn oem_id_from_resource(r: &ResourceSchema) -> Option<&str> {
113    r.base
114        .oem
115        .as_ref()
116        .and_then(|v| v.additional_properties.as_object())
117        .and_then(|v| v.keys().next())
118        .map(String::as_str)
119}
120
121/// The status and health of a resource and its children.
122#[cfg(feature = "resource-status")]
123#[derive(Clone, Debug)]
124pub struct Status {
125    /// The state of the resource.
126    pub state: Option<State>,
127    /// The health state of this resource in the absence of its dependent resources.
128    pub health: Option<Health>,
129    /// The overall health state from the view of this resource.
130    pub health_rollup: Option<Health>,
131}
132
133/// Represents Redfish resource that provides it's status.
134#[cfg(feature = "resource-status")]
135pub trait ResourceProvidesStatus {
136    /// Required function. Must be implemented for Redfish resources
137    /// that provides resource status.
138    fn resource_status_ref(&self) -> Option<&ResourceStatusSchema>;
139
140    /// Status of the resource if it is provided.
141    fn status(&self) -> Option<Status> {
142        self.resource_status_ref().map(|status| Status {
143            state: status.state.and_then(identity),
144            health: status.health.and_then(identity),
145            health_rollup: status.health_rollup.and_then(identity),
146        })
147    }
148}