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