qubit_argument/argument/argument_path.rs
1// =============================================================================
2// Copyright (c) 2025 - 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Structured paths that identify arguments in validation errors.
9
10use std::fmt::{
11 self,
12 Display,
13 Formatter,
14};
15
16/// An owned path identifying an argument or one of its nested components.
17///
18/// The path is stored exactly as supplied; this type does not parse or
19/// normalize separators.
20#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21pub struct ArgumentPath(String);
22
23impl ArgumentPath {
24 /// Creates an argument path by copying `path` without normalization.
25 ///
26 /// # Parameters
27 ///
28 /// - `path`: The path text to store.
29 ///
30 /// # Returns
31 ///
32 /// A new owned argument path.
33 #[inline]
34 pub fn new(path: &str) -> Self {
35 Self(path.to_owned())
36 }
37
38 /// Returns the stored path text.
39 ///
40 /// The returned string slice remains valid for the lifetime of this path.
41 #[inline]
42 pub fn as_str(&self) -> &str {
43 self.0.as_str()
44 }
45
46 /// Prepends a parent path component to this path.
47 ///
48 /// # Parameters
49 ///
50 /// - `prefix`: The parent path to place before the stored path.
51 ///
52 /// # Returns
53 ///
54 /// The composed path. Non-empty components are separated by one dot. If
55 /// either component is empty, no separator is added.
56 #[inline]
57 pub fn with_prefix(self, prefix: &str) -> Self {
58 if prefix.is_empty() {
59 return self;
60 }
61 if self.0.is_empty() {
62 return Self(prefix.to_owned());
63 }
64 let mut path = String::with_capacity(prefix.len() + 1 + self.0.len());
65 path.push_str(prefix);
66 path.push('.');
67 path.push_str(&self.0);
68 Self(path)
69 }
70}
71
72impl AsRef<str> for ArgumentPath {
73 /// Borrows the stored path as a string slice.
74 #[inline]
75 fn as_ref(&self) -> &str {
76 self.as_str()
77 }
78}
79
80impl Display for ArgumentPath {
81 /// Writes the stored path text without additional decoration.
82 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
83 formatter.write_str(self.as_str())
84 }
85}