tf_provider/
attribute_path.rs1use std::{borrow::Cow, fmt::Display};
20
21use crate::tfplugin6;
22
23#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
33pub struct AttributePath {
34 pub steps: Vec<AttributePathStep>,
35}
36
37impl AttributePath {
38 pub fn new<T: Into<Cow<'static, str>>>(name: T) -> Self {
44 Self {
45 steps: vec![AttributePathStep::Attribute(name.into())],
46 }
47 }
48
49 pub fn root() -> Self {
51 Self::default()
52 }
53
54 pub fn function_argument(index: i64) -> Self {
60 Self {
61 steps: vec![AttributePathStep::Index(index)],
62 }
63 }
64
65 pub fn attribute<T: Into<Cow<'static, str>>>(mut self, name: T) -> Self {
71 self.add_attribute(name);
72 self
73 }
74
75 pub fn key<T: Into<Cow<'static, str>>>(mut self, key: T) -> Self {
81 self.add_key(key);
82 self
83 }
84
85 pub fn index<T: Into<i64>>(mut self, idx: T) -> Self {
91 self.add_index(idx);
92 self
93 }
94
95 pub fn add_attribute<T: Into<Cow<'static, str>>>(&mut self, name: T) -> &mut Self {
101 self.steps.push(AttributePathStep::Attribute(name.into()));
102 self
103 }
104
105 pub fn add_key<T: Into<Cow<'static, str>>>(&mut self, key: T) -> &mut Self {
111 self.steps.push(AttributePathStep::Key(key.into()));
112 self
113 }
114
115 pub fn add_index<T: Into<i64>>(&mut self, idx: T) -> &mut Self {
121 self.steps.push(AttributePathStep::Index(idx.into()));
122 self
123 }
124
125 pub fn add_step(&mut self, step: AttributePathStep) -> &mut Self {
131 self.steps.push(step);
132 self
133 }
134
135 pub fn add_steps(&mut self, mut steps: AttributePath) -> &mut Self {
141 self.steps.append(&mut steps.steps);
142 self
143 }
144}
145
146impl Display for AttributePath {
147 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148 let mut sep = "";
149 for step in &self.steps {
150 match step {
151 AttributePathStep::Attribute(name) => {
152 f.write_fmt(format_args!("{}{}", sep, name))?
153 }
154 AttributePathStep::Key(key) => f.write_fmt(format_args!("[{:?}]", key))?,
155 AttributePathStep::Index(idx) => f.write_fmt(format_args!("[{}]", idx))?,
156 }
157 sep = ".";
158 }
159 Ok(())
160 }
161}
162
163impl std::ops::AddAssign<AttributePathStep> for AttributePath {
164 fn add_assign(&mut self, rhs: AttributePathStep) {
165 self.steps.push(rhs);
166 }
167}
168
169impl std::ops::Add<AttributePathStep> for AttributePath {
170 type Output = Self;
171 fn add(mut self, rhs: AttributePathStep) -> Self::Output {
172 self += rhs;
173 self
174 }
175}
176
177impl From<AttributePathStep> for AttributePath {
178 fn from(value: AttributePathStep) -> Self {
179 Self { steps: vec![value] }
180 }
181}
182
183impl From<AttributePath> for tfplugin6::AttributePath {
184 fn from(value: AttributePath) -> Self {
185 Self {
186 steps: value.steps.into_iter().map(|step| step.into()).collect(),
187 }
188 }
189}
190
191#[derive(Clone, PartialEq, Eq, Hash, Debug)]
193pub enum AttributePathStep {
194 Attribute(Cow<'static, str>),
196 Key(Cow<'static, str>),
198 Index(i64),
200}
201
202impl Display for AttributePathStep {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 match self {
205 AttributePathStep::Attribute(name) => f.write_str(name.as_ref()),
206 AttributePathStep::Key(key) => f.write_fmt(format_args!("[{:?}]", key)),
207 AttributePathStep::Index(idx) => f.write_fmt(format_args!("[{}]", idx)),
208 }
209 }
210}
211
212impl std::ops::Add<AttributePathStep> for AttributePathStep {
213 type Output = AttributePath;
214 fn add(self, rhs: AttributePathStep) -> Self::Output {
215 AttributePath {
216 steps: vec![self, rhs],
217 }
218 }
219}
220
221impl From<AttributePathStep> for tfplugin6::attribute_path::Step {
222 fn from(value: AttributePathStep) -> Self {
223 use tfplugin6::attribute_path::step::Selector;
224 Self {
225 selector: Some(match value {
226 AttributePathStep::Attribute(name) => Selector::AttributeName(name.into_owned()),
227 AttributePathStep::Key(key) => Selector::ElementKeyString(key.into_owned()),
228 AttributePathStep::Index(idx) => Selector::ElementKeyInt(idx),
229 }),
230 }
231 }
232}