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}