Skip to content

Commit 2cb2a06

Browse files
Overhaul the ffi::CStr documentation.
1 parent 8da694a commit 2cb2a06

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

src/libstd/ffi/c_str.rs

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,21 @@ pub struct CString {
128128

129129
/// Representation of a borrowed C string.
130130
///
131-
/// This dynamically sized type is only safely constructed via a borrowed
132-
/// version of an instance of `CString`. This type can be constructed from a raw
133-
/// C string as well and represents a C string borrowed from another location.
131+
/// This type represents a borrowed reference to a nul-terminated
132+
/// array of bytes. It can be constructed safely from a `&[`[`u8`]`]`
133+
/// slice, or unsafely from a raw `*const c_char`. It can then be
134+
/// converted to a Rust [`&str`] by performing UTF-8 validation, or
135+
/// into an owned [`CString`].
136+
///
137+
/// `CStr` is to [`CString`] as [`&str`] is to [`String`]: the former
138+
/// in each pair are borrowed references; the latter are owned
139+
/// strings.
134140
///
135141
/// Note that this structure is **not** `repr(C)` and is not recommended to be
136-
/// placed in the signatures of FFI functions. Instead safe wrappers of FFI
142+
/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI
137143
/// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
138144
/// interface to other consumers.
139145
///
140-
/// [`from_ptr`]: #method.from_ptr
141-
///
142146
/// # Examples
143147
///
144148
/// Inspecting a foreign C string:
@@ -151,7 +155,7 @@ pub struct CString {
151155
///
152156
/// unsafe {
153157
/// let slice = CStr::from_ptr(my_string());
154-
/// println!("string length: {}", slice.to_bytes().len());
158+
/// println!("string buffer size without nul terminator: {}", slice.to_bytes().len());
155159
/// }
156160
/// ```
157161
///
@@ -173,8 +177,6 @@ pub struct CString {
173177
///
174178
/// Converting a foreign C string into a Rust [`String`]:
175179
///
176-
/// [`String`]: ../string/struct.String.html
177-
///
178180
/// ```no_run
179181
/// use std::ffi::CStr;
180182
/// use std::os::raw::c_char;
@@ -189,6 +191,12 @@ pub struct CString {
189191
///
190192
/// println!("string: {}", my_string_safe());
191193
/// ```
194+
///
195+
/// [`u8`]: ../primitive.u8.html
196+
/// [`&str`]: ../primitive.str.html
197+
/// [`String`]: ../string/struct.String.html
198+
/// [`CString`]: struct.CString.html
199+
/// [`from_ptr`]: #method.from_ptr
192200
#[derive(Hash)]
193201
#[stable(feature = "rust1", since = "1.0.0")]
194202
pub struct CStr {
@@ -215,8 +223,10 @@ pub struct CStr {
215223
#[stable(feature = "rust1", since = "1.0.0")]
216224
pub struct NulError(usize, Vec<u8>);
217225

218-
/// An error returned from [`CStr::from_bytes_with_nul`] to indicate that a nul
219-
/// byte was found too early in the slice provided or one wasn't found at all.
226+
/// An error returned from [`CStr::from_bytes_with_nul`] to indicate
227+
/// that a nul byte was found too early in the slice provided, or one
228+
/// wasn't found at all. The slice used to create a `CStr` must have one
229+
/// and only one nul byte at the end of the slice.
220230
///
221231
/// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
222232
///
@@ -795,9 +805,9 @@ impl fmt::Display for IntoStringError {
795805
}
796806

797807
impl CStr {
798-
/// Casts a raw C string to a safe C string wrapper.
808+
/// Wraps a raw C string with a safe C string wrapper.
799809
///
800-
/// This function will cast the provided `ptr` to the `CStr` wrapper which
810+
/// This function will wrap the provided `ptr` with a `CStr` wrapper, which
801811
/// allows inspection and interoperation of non-owned C strings. This method
802812
/// is unsafe for a number of reasons:
803813
///
@@ -837,9 +847,9 @@ impl CStr {
837847

838848
/// Creates a C string wrapper from a byte slice.
839849
///
840-
/// This function will cast the provided `bytes` to a `CStr` wrapper after
841-
/// ensuring that it is null terminated and does not contain any interior
842-
/// nul bytes.
850+
/// This function will cast the provided `bytes` to a `CStr`
851+
/// wrapper after ensuring that the byte slice is nul-terminated
852+
/// and does not contain any interior nul bytes.
843853
///
844854
/// # Examples
845855
///
@@ -884,7 +894,7 @@ impl CStr {
884894
/// Unsafely creates a C string wrapper from a byte slice.
885895
///
886896
/// This function will cast the provided `bytes` to a `CStr` wrapper without
887-
/// performing any sanity checks. The provided slice must be null terminated
897+
/// performing any sanity checks. The provided slice **must** be nul-terminated
888898
/// and not contain any interior nul bytes.
889899
///
890900
/// # Examples
@@ -906,7 +916,7 @@ impl CStr {
906916

907917
/// Returns the inner pointer to this C string.
908918
///
909-
/// The returned pointer will be valid for as long as `self` is and points
919+
/// The returned pointer will be valid for as long as `self` is, and points
910920
/// to a contiguous region of memory terminated with a 0 byte to represent
911921
/// the end of the string.
912922
///
@@ -927,9 +937,9 @@ impl CStr {
927937
/// ```
928938
///
929939
/// This happens because the pointer returned by `as_ptr` does not carry any
930-
/// lifetime information and the string is deallocated immediately after
940+
/// lifetime information and the [`CString`] is deallocated immediately after
931941
/// the `CString::new("Hello").unwrap().as_ptr()` expression is evaluated.
932-
/// To fix the problem, bind the string to a local variable:
942+
/// To fix the problem, bind the `CString` to a local variable:
933943
///
934944
/// ```no_run
935945
/// use std::ffi::{CString};
@@ -941,6 +951,11 @@ impl CStr {
941951
/// *ptr;
942952
/// }
943953
/// ```
954+
///
955+
/// This way, the lifetime of the `CString` in `hello` encompasses
956+
/// the lifetime of `ptr` and the `unsafe` block.
957+
///
958+
/// [`CString`]: struct.CString.html
944959
#[inline]
945960
#[stable(feature = "rust1", since = "1.0.0")]
946961
pub fn as_ptr(&self) -> *const c_char {
@@ -949,10 +964,6 @@ impl CStr {
949964

950965
/// Converts this C string to a byte slice.
951966
///
952-
/// This function will calculate the length of this string (which normally
953-
/// requires a linear amount of work to be done) and then return the
954-
/// resulting slice of `u8` elements.
955-
///
956967
/// The returned slice will **not** contain the trailing nul terminator that this C
957968
/// string has.
958969
///
@@ -1002,8 +1013,9 @@ impl CStr {
10021013

10031014
/// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
10041015
///
1005-
/// This function will calculate the length of this string and check for
1006-
/// UTF-8 validity, and then return the [`&str`] if it's valid.
1016+
/// If the contents of the `CStr` are valid UTF-8 data, this
1017+
/// function will return the corresponding [`&str`] slice. Otherwise,
1018+
/// it will return an error with details of where UTF-8 validation failed.
10071019
///
10081020
/// > **Note**: This method is currently implemented to check for validity
10091021
/// > after a 0-cost cast, but it is planned to alter its definition in the
@@ -1031,18 +1043,22 @@ impl CStr {
10311043

10321044
/// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`.
10331045
///
1034-
/// This function will calculate the length of this string (which normally
1035-
/// requires a linear amount of work to be done) and then return the
1036-
/// resulting slice as a [`Cow`]`<`[`str`]`>`, replacing any invalid UTF-8 sequences
1037-
/// with `U+FFFD REPLACEMENT CHARACTER`.
1046+
/// If the contents of the `CStr` are valid UTF-8 data, this
1047+
/// function will return a [`Cow`]`::`[`Borrowed`]`(`[`&str`]`)`
1048+
/// with the the corresponding [`&str`] slice. Otherwise, it will
1049+
/// replace any invalid UTF-8 sequences with `U+FFFD REPLACEMENT
1050+
/// CHARACTER` and return a [`Cow`]`::`[`Owned`]`(`[`String`]`)`
1051+
/// with the result.
10381052
///
10391053
/// > **Note**: This method is currently implemented to check for validity
10401054
/// > after a 0-cost cast, but it is planned to alter its definition in the
10411055
/// > future to perform the length calculation in addition to the UTF-8
10421056
/// > check whenever this method is called.
10431057
///
10441058
/// [`Cow`]: ../borrow/enum.Cow.html
1059+
/// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
10451060
/// [`str`]: ../primitive.str.html
1061+
/// [`String`]: ../string/struct.String.html
10461062
///
10471063
/// # Examples
10481064
///

0 commit comments

Comments
 (0)