cstring_array/traits.rs
1// SPDX-FileCopyrightText: 2025 RAprogramm <andrey.rozanov.vl@gmail.com>
2//
3// SPDX-License-Identifier: MIT
4
5//! Trait implementations for CStringArray.
6//!
7//! This module provides ergonomic conversions from various string collection
8//! types into `CStringArray` through the `TryFrom` trait. These implementations
9//! allow for flexible and convenient array construction from different input
10//! formats.
11
12use std::ffi::CString;
13
14use crate::{array::CStringArray, error::CStringArrayError};
15
16impl TryFrom<Vec<String>> for CStringArray {
17 type Error = CStringArrayError;
18
19 /// Converts a `Vec<String>` into a `CStringArray`.
20 ///
21 /// # Errors
22 ///
23 /// Returns an error if any string contains an interior null byte or if the
24 /// vector is empty.
25 ///
26 /// # Example
27 ///
28 /// ```
29 /// use std::convert::TryFrom;
30 ///
31 /// use cstring_array::CStringArray;
32 ///
33 /// let strings = vec!["hello".to_string(), "world".to_string()];
34 /// let array = CStringArray::try_from(strings).unwrap();
35 /// assert_eq!(array.len(), 2);
36 /// ```
37 fn try_from(strings: Vec<String>) -> Result<Self, Self::Error> {
38 CStringArray::new(strings)
39 }
40}
41
42impl TryFrom<Vec<&str>> for CStringArray {
43 type Error = CStringArrayError;
44
45 /// Converts a `Vec<&str>` into a `CStringArray`.
46 ///
47 /// # Errors
48 ///
49 /// Returns an error if any string contains an interior null byte or if the
50 /// vector is empty.
51 ///
52 /// # Example
53 ///
54 /// ```
55 /// use std::convert::TryFrom;
56 ///
57 /// use cstring_array::CStringArray;
58 ///
59 /// let strings = vec!["hello", "world"];
60 /// let array = CStringArray::try_from(strings).unwrap();
61 /// assert_eq!(array.len(), 2);
62 /// ```
63 fn try_from(strings: Vec<&str>) -> Result<Self, Self::Error> {
64 let owned: Vec<String> = strings.into_iter().map(String::from).collect();
65 CStringArray::new(owned)
66 }
67}
68
69impl<const N: usize> TryFrom<[String; N]> for CStringArray {
70 type Error = CStringArrayError;
71
72 /// Converts an array of `String`s into a `CStringArray`.
73 ///
74 /// # Errors
75 ///
76 /// Returns an error if any string contains an interior null byte or if the
77 /// array is empty.
78 ///
79 /// # Example
80 ///
81 /// ```
82 /// use std::convert::TryFrom;
83 ///
84 /// use cstring_array::CStringArray;
85 ///
86 /// let strings = ["hello".to_string(), "world".to_string()];
87 /// let array = CStringArray::try_from(strings).unwrap();
88 /// assert_eq!(array.len(), 2);
89 /// ```
90 fn try_from(strings: [String; N]) -> Result<Self, Self::Error> {
91 CStringArray::new(strings.to_vec())
92 }
93}
94
95impl<const N: usize> TryFrom<[&str; N]> for CStringArray {
96 type Error = CStringArrayError;
97
98 /// Converts an array of string slices into a `CStringArray`.
99 ///
100 /// # Errors
101 ///
102 /// Returns an error if any string contains an interior null byte or if the
103 /// array is empty.
104 ///
105 /// # Example
106 ///
107 /// ```
108 /// use std::convert::TryFrom;
109 ///
110 /// use cstring_array::CStringArray;
111 ///
112 /// let strings = ["hello", "world"];
113 /// let array = CStringArray::try_from(strings).unwrap();
114 /// assert_eq!(array.len(), 2);
115 /// ```
116 fn try_from(strings: [&str; N]) -> Result<Self, Self::Error> {
117 let owned: Vec<String> = strings.into_iter().map(String::from).collect();
118 CStringArray::new(owned)
119 }
120}
121
122impl TryFrom<Vec<CString>> for CStringArray {
123 type Error = CStringArrayError;
124
125 /// Converts a `Vec<CString>` into a `CStringArray` (zero-copy).
126 ///
127 /// # Errors
128 ///
129 /// Returns an error if the vector is empty.
130 ///
131 /// # Example
132 ///
133 /// ```
134 /// use std::{convert::TryFrom, ffi::CString};
135 ///
136 /// use cstring_array::CStringArray;
137 ///
138 /// let cstrings = vec![
139 /// CString::new("hello").unwrap(),
140 /// CString::new("world").unwrap(),
141 /// ];
142 /// let array = CStringArray::try_from(cstrings).unwrap();
143 /// assert_eq!(array.len(), 2);
144 /// ```
145 fn try_from(strings: Vec<CString>) -> Result<Self, Self::Error> {
146 CStringArray::from_cstrings(strings)
147 }
148}