diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..56ad0f8 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,5 @@ +[build] +target = "wasm32-wasi" + +[target.wasm32-wasi] +runner = "wasmedge" \ No newline at end of file diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2ca91c8..e5b5f52 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,9 +9,9 @@ jobs: steps: - uses: actions/checkout@v1 + - name: Setup Rust Toolchain + run: | + rustup update + rustup target add wasm32-wasi - name: Build run: cargo build --verbose - - name: Build with Rusttls - run: cargo build --verbose --no-default-features --features rust-tls - - name: Run tests - run: cargo test --verbose diff --git a/.gitignore b/.gitignore index a008342..c6452f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target **/*.rs.bk -.DS_store \ No newline at end of file +.DS_store +__pycache__ \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c6f731a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,41 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "libc" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasmedge_http_req" +version = "0.8.2" +dependencies = [ + "unicase", + "wasmedge_wasi_socket", +] + +[[package]] +name = "wasmedge_wasi_socket" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d186f3dd4f60a3e30d50a9a4c7059cfcc9fbb59eaa0256b1596259806ef56e46" +dependencies = [ + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 3f3338e..1c3c693 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmedge_http_req" -version = "0.8.1" +version = "0.8.2" license = "MIT" description = "HTTP client for the WasmEdge network socket API. Derived from the http_req library." repository = "https://github.com/second-state/wasmedge_http_req" @@ -12,4 +12,4 @@ edition = "2018" [dependencies] unicase = "^2.6" -wasmedge_wasi_socket = "0.1.0" +wasmedge_wasi_socket = "0.3" diff --git a/benches/bench.rs b/benches/bench.rs deleted file mode 100644 index c877159..0000000 --- a/benches/bench.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![feature(test)] -extern crate http_req; -extern crate test; - -use http_req::{request::Request, response::Response, uri::Uri}; -use std::{convert::TryFrom, fs::File, io::Read, time::Duration}; -use test::Bencher; - -#[bench] -fn parse_response(b: &mut Bencher) { - let mut content = Vec::new(); - let mut response = File::open("benches/res.txt").unwrap(); - response.read_to_end(&mut content).unwrap(); - - b.iter(|| { - let mut body = Vec::new(); - Response::try_from(&content, &mut body) - }); -} - -const URI: &str = "https://www.rust-lang.org/"; - -#[bench] -fn request_send(b: &mut Bencher) { - b.iter(|| { - let uri = Uri::try_from(URI).unwrap(); - let timeout = Some(Duration::from_secs(6)); - let mut writer = Vec::new(); - - let res = Request::new(&uri) - .timeout(timeout) - .send(&mut writer) - .unwrap(); - - res - }); -} - -#[bench] -fn parse_uri(b: &mut Bencher) { - b.iter(|| Uri::try_from(URI)); -} diff --git a/benches/res.txt b/benches/res.txt deleted file mode 100644 index f06cf2b..0000000 --- a/benches/res.txt +++ /dev/null @@ -1,2063 +0,0 @@ -HTTP/1.1 200 OK -Content-Type: text/html -Content-Length: 510628 -Connection: close -Date: Mon, 13 Aug 2018 17:14:25 GMT -ETag: "09ce5f81f7dea9790773b0e4f29c0a34" -Last-Modified: Fri, 10 Aug 2018 03:44:20 GMT -Server: AmazonS3 -x-amz-version-id: okxx6WQRSEhWqGgZbtNrVcL43oyuB8Ce -Vary: Accept-Encoding -X-Cache: Miss from cloudfront -Via: 1.1 f62050e21268ac5026b6ccb68a1f0a2b.cloudfront.net (CloudFront) -X-Amz-Cf-Id: vRAWzTLuy7iw8LiuOHiK9d6SJmDhqjnYu3wtprO_TQS5kRxAfY9UoQ== - -std::string::String - Rust

Struct std::string::String1.0.0[][src]

pub struct String { /* fields omitted */ }

A UTF-8 encoded, growable string.

-

The String type is the most common string type that has ownership over the -contents of the string. It has a close relationship with its borrowed -counterpart, the primitive str.

-

Examples

-

You can create a String from a literal string with String::from:

- -
-let hello = String::from("Hello, world!");Run
-

You can append a char to a String with the push method, and -append a &str with the push_str method:

- -
-let mut hello = String::from("Hello, ");
-
-hello.push('w');
-hello.push_str("orld!");Run
-

If you have a vector of UTF-8 bytes, you can create a String from it with -the from_utf8 method:

- -
-// some bytes, in a vector
-let sparkle_heart = vec![240, 159, 146, 150];
-
-// We know these bytes are valid, so we'll use `unwrap()`.
-let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
-
-assert_eq!("💖", sparkle_heart);Run
-

UTF-8

-

Strings are always valid UTF-8. This has a few implications, the first of -which is that if you need a non-UTF-8 string, consider OsString. It is -similar, but without the UTF-8 constraint. The second implication is that -you cannot index into a String:

- -
This example deliberately fails to compile
-let s = "hello";
-
-println!("The first letter of s is {}", s[0]); // ERROR!!!Run
-

Indexing is intended to be a constant-time operation, but UTF-8 encoding -does not allow us to do this. Furthermore, it's not clear what sort of -thing the index should return: a byte, a codepoint, or a grapheme cluster. -The bytes and chars methods return iterators over the first -two, respectively.

-

Deref

-

Strings implement Deref<Target=str>, and so inherit all of str's -methods. In addition, this means that you can pass a String to a -function which takes a &str by using an ampersand (&):

- -
-fn takes_str(s: &str) { }
-
-let s = String::from("Hello");
-
-takes_str(&s);Run
-

This will create a &str from the String and pass it in. This -conversion is very inexpensive, and so generally, functions will accept -&strs as arguments unless they need a String for some specific -reason.

-

In certain cases Rust doesn't have enough information to make this -conversion, known as Deref coercion. In the following example a string -slice &'a str implements the trait TraitExample, and the function -example_func takes anything that implements the trait. In this case Rust -would need to make two implicit conversions, which Rust doesn't have the -means to do. For that reason, the following example will not compile.

- -
This example deliberately fails to compile
-trait TraitExample {}
-
-impl<'a> TraitExample for &'a str {}
-
-fn example_func<A: TraitExample>(example_arg: A) {}
-
-fn main() {
-    let example_string = String::from("example_string");
-    example_func(&example_string);
-}Run
-

There are two options that would work instead. The first would be to -change the line example_func(&example_string); to -example_func(example_string.as_str());, using the method as_str() -to explicitly extract the string slice containing the string. The second -way changes example_func(&example_string); to -example_func(&*example_string);. In this case we are dereferencing a -String to a str, then referencing the str back to -&str. The second way is more idiomatic, however both work to do the -conversion explicitly rather than relying on the implicit conversion.

-

Representation

-

A String is made up of three components: a pointer to some bytes, a -length, and a capacity. The pointer points to an internal buffer String -uses to store its data. The length is the number of bytes currently stored -in the buffer, and the capacity is the size of the buffer in bytes. As such, -the length will always be less than or equal to the capacity.

-

This buffer is always stored on the heap.

-

You can look at these with the as_ptr, len, and capacity -methods:

- -
-use std::mem;
-
-let story = String::from("Once upon a time...");
-
-let ptr = story.as_ptr();
-let len = story.len();
-let capacity = story.capacity();
-
-// story has nineteen bytes
-assert_eq!(19, len);
-
-// Now that we have our parts, we throw the story away.
-mem::forget(story);
-
-// We can re-build a String out of ptr, len, and capacity. This is all
-// unsafe because we are responsible for making sure the components are
-// valid:
-let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
-
-assert_eq!(String::from("Once upon a time..."), s);Run
-

If a String has enough capacity, adding elements to it will not -re-allocate. For example, consider this program:

- -
-let mut s = String::new();
-
-println!("{}", s.capacity());
-
-for _ in 0..5 {
-    s.push_str("hello");
-    println!("{}", s.capacity());
-}Run
-

This will output the following:

-
0
-5
-10
-20
-20
-40
-
-

At first, we have no memory allocated at all, but as we append to the -string, it increases its capacity appropriately. If we instead use the -with_capacity method to allocate the correct capacity initially:

- -
-let mut s = String::with_capacity(25);
-
-println!("{}", s.capacity());
-
-for _ in 0..5 {
-    s.push_str("hello");
-    println!("{}", s.capacity());
-}Run
-

We end up with a different output:

-
25
-25
-25
-25
-25
-25
-
-

Here, there's no need to allocate more memory inside the loop.

-

Methods

impl String
[src]

Creates a new empty String.

-

Given that the String is empty, this will not allocate any initial -buffer. While that means that this initial operation is very -inexpensive, it may cause excessive allocation later when you add -data. If you have an idea of how much data the String will hold, -consider the with_capacity method to prevent excessive -re-allocation.

-

Examples

-

Basic usage:

- -
-let s = String::new();Run
-

Creates a new empty String with a particular capacity.

-

Strings have an internal buffer to hold their data. The capacity is -the length of that buffer, and can be queried with the capacity -method. This method creates an empty String, but one with an initial -buffer that can hold capacity bytes. This is useful when you may be -appending a bunch of data to the String, reducing the number of -reallocations it needs to do.

-

If the given capacity is 0, no allocation will occur, and this method -is identical to the new method.

-

Examples

-

Basic usage:

- -
-let mut s = String::with_capacity(10);
-
-// The String contains no chars, even though it has capacity for more
-assert_eq!(s.len(), 0);
-
-// These are all done without reallocating...
-let cap = s.capacity();
-for i in 0..10 {
-    s.push('a');
-}
-
-assert_eq!(s.capacity(), cap);
-
-// ...but this may make the vector reallocate
-s.push('a');Run
-

Converts a vector of bytes to a String.

-

A string slice (&str) is made of bytes (u8), and a vector of bytes -(Vec<u8>) is made of bytes, so this function converts between the -two. Not all byte slices are valid Strings, however: String -requires that it is valid UTF-8. from_utf8() checks to ensure that -the bytes are valid UTF-8, and then does the conversion.

-

If you are sure that the byte slice is valid UTF-8, and you don't want -to incur the overhead of the validity check, there is an unsafe version -of this function, from_utf8_unchecked, which has the same behavior -but skips the check.

-

This method will take care to not copy the vector, for efficiency's -sake.

-

If you need a &str instead of a String, consider -str::from_utf8.

-

The inverse of this method is as_bytes.

-

Errors

-

Returns Err if the slice is not UTF-8 with a description as to why the -provided bytes are not UTF-8. The vector you moved in is also included.

-

Examples

-

Basic usage:

- -
-// some bytes, in a vector
-let sparkle_heart = vec![240, 159, 146, 150];
-
-// We know these bytes are valid, so we'll use `unwrap()`.
-let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
-
-assert_eq!("💖", sparkle_heart);Run
-

Incorrect bytes:

- -
-// some invalid bytes, in a vector
-let sparkle_heart = vec![0, 159, 146, 150];
-
-assert!(String::from_utf8(sparkle_heart).is_err());Run
-

See the docs for FromUtf8Error for more details on what you can do -with this error.

-

Converts a slice of bytes to a string, including invalid characters.

-

Strings are made of bytes (u8), and a slice of bytes -(&[u8]) is made of bytes, so this function converts -between the two. Not all byte slices are valid strings, however: strings -are required to be valid UTF-8. During this conversion, -from_utf8_lossy() will replace any invalid UTF-8 sequences with -U+FFFD REPLACEMENT CHARACTER, which looks like this: �

-

If you are sure that the byte slice is valid UTF-8, and you don't want -to incur the overhead of the conversion, there is an unsafe version -of this function, from_utf8_unchecked, which has the same behavior -but skips the checks.

-

This function returns a Cow<'a, str>. If our byte slice is invalid -UTF-8, then we need to insert the replacement characters, which will -change the size of the string, and hence, require a String. But if -it's already valid UTF-8, we don't need a new allocation. This return -type allows us to handle both cases.

-

Examples

-

Basic usage:

- -
-// some bytes, in a vector
-let sparkle_heart = vec![240, 159, 146, 150];
-
-let sparkle_heart = String::from_utf8_lossy(&sparkle_heart);
-
-assert_eq!("💖", sparkle_heart);Run
-

Incorrect bytes:

- -
-// some invalid bytes
-let input = b"Hello \xF0\x90\x80World";
-let output = String::from_utf8_lossy(input);
-
-assert_eq!("Hello �World", output);Run
-

Decode a UTF-16 encoded vector v into a String, returning Err -if v contains any invalid data.

-

Examples

-

Basic usage:

- -
-// 𝄞music
-let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
-          0x0073, 0x0069, 0x0063];
-assert_eq!(String::from("𝄞music"),
-           String::from_utf16(v).unwrap());
-
-// 𝄞mu<invalid>ic
-let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
-          0xD800, 0x0069, 0x0063];
-assert!(String::from_utf16(v).is_err());Run
-

Decode a UTF-16 encoded slice v into a String, replacing -invalid data with the replacement character (U+FFFD).

-

Unlike from_utf8_lossy which returns a Cow<'a, str>, -from_utf16_lossy returns a String since the UTF-16 to UTF-8 -conversion requires a memory allocation.

-

Examples

-

Basic usage:

- -
-// 𝄞mus<invalid>ic<invalid>
-let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
-          0x0073, 0xDD1E, 0x0069, 0x0063,
-          0xD834];
-
-assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
-           String::from_utf16_lossy(v));Run
-

Creates a new String from a length, capacity, and pointer.

-

Safety

-

This is highly unsafe, due to the number of invariants that aren't -checked:

-
    -
  • The memory at ptr needs to have been previously allocated by the -same allocator the standard library uses.
  • -
  • length needs to be less than or equal to capacity.
  • -
  • capacity needs to be the correct value.
  • -
-

Violating these may cause problems like corrupting the allocator's -internal data structures.

-

The ownership of ptr is effectively transferred to the -String which may then deallocate, reallocate or change the -contents of memory pointed to by the pointer at will. Ensure -that nothing else uses the pointer after calling this -function.

-

Examples

-

Basic usage:

- -
-use std::mem;
-
-unsafe {
-    let s = String::from("hello");
-    let ptr = s.as_ptr();
-    let len = s.len();
-    let capacity = s.capacity();
-
-    mem::forget(s);
-
-    let s = String::from_raw_parts(ptr as *mut _, len, capacity);
-
-    assert_eq!(String::from("hello"), s);
-}Run
-

Converts a vector of bytes to a String without checking that the -string contains valid UTF-8.

-

See the safe version, from_utf8, for more details.

-

Safety

-

This function is unsafe because it does not check that the bytes passed -to it are valid UTF-8. If this constraint is violated, it may cause -memory unsafety issues with future users of the String, as the rest of -the standard library assumes that Strings are valid UTF-8.

-

Examples

-

Basic usage:

- -
-// some bytes, in a vector
-let sparkle_heart = vec![240, 159, 146, 150];
-
-let sparkle_heart = unsafe {
-    String::from_utf8_unchecked(sparkle_heart)
-};
-
-assert_eq!("💖", sparkle_heart);Run
-

Important traits for Vec<u8>

Converts a String into a byte vector.

-

This consumes the String, so we do not need to copy its contents.

-

Examples

-

Basic usage:

- -
-let s = String::from("hello");
-let bytes = s.into_bytes();
-
-assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);Run
-

Extracts a string slice containing the entire string.

-

Examples

-

Basic usage:

- -
-let s = String::from("foo");
-
-assert_eq!("foo", s.as_str());Run
-

Converts a String into a mutable string slice.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foobar");
-let s_mut_str = s.as_mut_str();
-
-s_mut_str.make_ascii_uppercase();
-
-assert_eq!("FOOBAR", s_mut_str);Run
-

Appends a given string slice onto the end of this String.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foo");
-
-s.push_str("bar");
-
-assert_eq!("foobar", s);Run
-

Returns this String's capacity, in bytes.

-

Examples

-

Basic usage:

- -
-let s = String::with_capacity(10);
-
-assert!(s.capacity() >= 10);Run
-

Ensures that this String's capacity is at least additional bytes -larger than its length.

-

The capacity may be increased by more than additional bytes if it -chooses, to prevent frequent reallocations.

-

If you do not want this "at least" behavior, see the reserve_exact -method.

-

Panics

-

Panics if the new capacity overflows usize.

-

Examples

-

Basic usage:

- -
-let mut s = String::new();
-
-s.reserve(10);
-
-assert!(s.capacity() >= 10);Run
-

This may not actually increase the capacity:

- -
-let mut s = String::with_capacity(10);
-s.push('a');
-s.push('b');
-
-// s now has a length of 2 and a capacity of 10
-assert_eq!(2, s.len());
-assert_eq!(10, s.capacity());
-
-// Since we already have an extra 8 capacity, calling this...
-s.reserve(8);
-
-// ... doesn't actually increase.
-assert_eq!(10, s.capacity());Run
-

Ensures that this String's capacity is additional bytes -larger than its length.

-

Consider using the reserve method unless you absolutely know -better than the allocator.

-

Panics

-

Panics if the new capacity overflows usize.

-

Examples

-

Basic usage:

- -
-let mut s = String::new();
-
-s.reserve_exact(10);
-
-assert!(s.capacity() >= 10);Run
-

This may not actually increase the capacity:

- -
-let mut s = String::with_capacity(10);
-s.push('a');
-s.push('b');
-
-// s now has a length of 2 and a capacity of 10
-assert_eq!(2, s.len());
-assert_eq!(10, s.capacity());
-
-// Since we already have an extra 8 capacity, calling this...
-s.reserve_exact(8);
-
-// ... doesn't actually increase.
-assert_eq!(10, s.capacity());Run
-

🔬 This is a nightly-only experimental API. (try_reserve #48043)

new API

-

Tries to reserve capacity for at least additional more elements to be inserted -in the given String. The collection may reserve more space to avoid -frequent reallocations. After calling reserve, capacity will be -greater than or equal to self.len() + additional. Does nothing if -capacity is already sufficient.

-

Errors

-

If the capacity overflows, or the allocator reports a failure, then an error -is returned.

-

Examples

-
-#![feature(try_reserve)]
-use std::collections::CollectionAllocErr;
-
-fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
-    let mut output = String::new();
-
-    // Pre-reserve the memory, exiting if we can't
-    output.try_reserve(data.len())?;
-
-    // Now we know this can't OOM in the middle of our complex work
-    output.push_str(data);
-
-    Ok(output)
-}Run
-

🔬 This is a nightly-only experimental API. (try_reserve #48043)

new API

-

Tries to reserves the minimum capacity for exactly additional more elements to -be inserted in the given String. After calling reserve_exact, -capacity will be greater than or equal to self.len() + additional. -Does nothing if the capacity is already sufficient.

-

Note that the allocator may give the collection more space than it -requests. Therefore capacity can not be relied upon to be precisely -minimal. Prefer reserve if future insertions are expected.

-

Errors

-

If the capacity overflows, or the allocator reports a failure, then an error -is returned.

-

Examples

-
-#![feature(try_reserve)]
-use std::collections::CollectionAllocErr;
-
-fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
-    let mut output = String::new();
-
-    // Pre-reserve the memory, exiting if we can't
-    output.try_reserve(data.len())?;
-
-    // Now we know this can't OOM in the middle of our complex work
-    output.push_str(data);
-
-    Ok(output)
-}Run
-

Shrinks the capacity of this String to match its length.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foo");
-
-s.reserve(100);
-assert!(s.capacity() >= 100);
-
-s.shrink_to_fit();
-assert_eq!(3, s.capacity());Run
-

🔬 This is a nightly-only experimental API. (shrink_to)

new API

-

Shrinks the capacity of this String with a lower bound.

-

The capacity will remain at least as large as both the length -and the supplied value.

-

Panics if the current capacity is smaller than the supplied -minimum capacity.

-

Examples

-
-#![feature(shrink_to)]
-let mut s = String::from("foo");
-
-s.reserve(100);
-assert!(s.capacity() >= 100);
-
-s.shrink_to(10);
-assert!(s.capacity() >= 10);
-s.shrink_to(0);
-assert!(s.capacity() >= 3);Run
-

Appends the given char to the end of this String.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("abc");
-
-s.push('1');
-s.push('2');
-s.push('3');
-
-assert_eq!("abc123", s);Run
-

Important traits for &'a [u8]

Returns a byte slice of this String's contents.

-

The inverse of this method is from_utf8.

-

Examples

-

Basic usage:

- -
-let s = String::from("hello");
-
-assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());Run
-

Shortens this String to the specified length.

-

If new_len is greater than the string's current length, this has no -effect.

-

Note that this method has no effect on the allocated capacity -of the string

-

Panics

-

Panics if new_len does not lie on a char boundary.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("hello");
-
-s.truncate(2);
-
-assert_eq!("he", s);Run
-

Removes the last character from the string buffer and returns it.

-

Returns None if this String is empty.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foo");
-
-assert_eq!(s.pop(), Some('o'));
-assert_eq!(s.pop(), Some('o'));
-assert_eq!(s.pop(), Some('f'));
-
-assert_eq!(s.pop(), None);Run
-

Removes a char from this String at a byte position and returns it.

-

This is an O(n) operation, as it requires copying every element in the -buffer.

-

Panics

-

Panics if idx is larger than or equal to the String's length, -or if it does not lie on a char boundary.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foo");
-
-assert_eq!(s.remove(0), 'f');
-assert_eq!(s.remove(1), 'o');
-assert_eq!(s.remove(0), 'o');Run
-

Retains only the characters specified by the predicate.

-

In other words, remove all characters c such that f(c) returns false. -This method operates in place and preserves the order of the retained -characters.

-

Examples

-
-let mut s = String::from("f_o_ob_ar");
-
-s.retain(|c| c != '_');
-
-assert_eq!(s, "foobar");Run
-

Inserts a character into this String at a byte position.

-

This is an O(n) operation as it requires copying every element in the -buffer.

-

Panics

-

Panics if idx is larger than the String's length, or if it does not -lie on a char boundary.

-

Examples

-

Basic usage:

- -
-let mut s = String::with_capacity(3);
-
-s.insert(0, 'f');
-s.insert(1, 'o');
-s.insert(2, 'o');
-
-assert_eq!("foo", s);Run
-

Inserts a string slice into this String at a byte position.

-

This is an O(n) operation as it requires copying every element in the -buffer.

-

Panics

-

Panics if idx is larger than the String's length, or if it does not -lie on a char boundary.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("bar");
-
-s.insert_str(0, "foo");
-
-assert_eq!("foobar", s);Run
-

Important traits for Vec<u8>

Returns a mutable reference to the contents of this String.

-

Safety

-

This function is unsafe because it does not check that the bytes passed -to it are valid UTF-8. If this constraint is violated, it may cause -memory unsafety issues with future users of the String, as the rest of -the standard library assumes that Strings are valid UTF-8.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("hello");
-
-unsafe {
-    let vec = s.as_mut_vec();
-    assert_eq!(&[104, 101, 108, 108, 111][..], &vec[..]);
-
-    vec.reverse();
-}
-assert_eq!(s, "olleh");Run
-

Returns the length of this String, in bytes.

-

Examples

-

Basic usage:

- -
-let a = String::from("foo");
-
-assert_eq!(a.len(), 3);Run
-

Returns true if this String has a length of zero.

-

Returns false otherwise.

-

Examples

-

Basic usage:

- -
-let mut v = String::new();
-assert!(v.is_empty());
-
-v.push('a');
-assert!(!v.is_empty());Run
-

Splits the string into two at the given index.

-

Returns a newly allocated String. self contains bytes [0, at), and -the returned String contains bytes [at, len). at must be on the -boundary of a UTF-8 code point.

-

Note that the capacity of self does not change.

-

Panics

-

Panics if at is not on a UTF-8 code point boundary, or if it is beyond the last -code point of the string.

-

Examples

-
-let mut hello = String::from("Hello, World!");
-let world = hello.split_off(7);
-assert_eq!(hello, "Hello, ");
-assert_eq!(world, "World!");Run
-

Truncates this String, removing all contents.

-

While this means the String will have a length of zero, it does not -touch its capacity.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("foo");
-
-s.clear();
-
-assert!(s.is_empty());
-assert_eq!(0, s.len());
-assert_eq!(3, s.capacity());Run
-

Important traits for Drain<'a>

Creates a draining iterator that removes the specified range in the string -and yields the removed chars.

-

Note: The element range is removed even if the iterator is not -consumed until the end.

-

Panics

-

Panics if the starting point or end point do not lie on a char -boundary, or if they're out of bounds.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("α is alpha, β is beta");
-let beta_offset = s.find('β').unwrap_or(s.len());
-
-// Remove the range up until the β from the string
-let t: String = s.drain(..beta_offset).collect();
-assert_eq!(t, "α is alpha, ");
-assert_eq!(s, "β is beta");
-
-// A full range clears the string
-s.drain(..);
-assert_eq!(s, "");Run
-

Removes the specified range in the string, -and replaces it with the given string. -The given string doesn't need to be the same length as the range.

-

Panics

-

Panics if the starting point or end point do not lie on a char -boundary, or if they're out of bounds.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("α is alpha, β is beta");
-let beta_offset = s.find('β').unwrap_or(s.len());
-
-// Replace the range up until the β from the string
-s.replace_range(..beta_offset, "Α is capital alpha; ");
-assert_eq!(s, "Α is capital alpha; β is beta");Run
-

Important traits for Box<I>

Converts this String into a Box<str>.

-

This will drop any excess capacity.

-

Examples

-

Basic usage:

- -
-let s = String::from("hello");
-
-let b = s.into_boxed_str();Run
-

Methods from Deref<Target = str>

Returns the length of self.

-

This length is in bytes, not chars or graphemes. In other words, -it may not be what a human considers the length of the string.

-

Examples

-

Basic usage:

- -
-let len = "foo".len();
-assert_eq!(3, len);
-
-let len = "ƒoo".len(); // fancy f!
-assert_eq!(4, len);Run
-

Returns true if self has a length of zero bytes.

-

Examples

-

Basic usage:

- -
-let s = "";
-assert!(s.is_empty());
-
-let s = "not empty";
-assert!(!s.is_empty());Run
-

Checks that index-th byte lies at the start and/or end of a -UTF-8 code point sequence.

-

The start and end of the string (when index == self.len()) are -considered to be -boundaries.

-

Returns false if index is greater than self.len().

-

Examples

-
-let s = "Löwe 老虎 Léopard";
-assert!(s.is_char_boundary(0));
-// start of `老`
-assert!(s.is_char_boundary(6));
-assert!(s.is_char_boundary(s.len()));
-
-// second byte of `ö`
-assert!(!s.is_char_boundary(2));
-
-// third byte of `老`
-assert!(!s.is_char_boundary(8));Run
-

Important traits for &'a [u8]

Converts a string slice to a byte slice. To convert the byte slice back -into a string slice, use the str::from_utf8 function.

-

Examples

-

Basic usage:

- -
-let bytes = "bors".as_bytes();
-assert_eq!(b"bors", bytes);Run
-

Important traits for &'a [u8]

Converts a mutable string slice to a mutable byte slice. To convert the -mutable byte slice back into a mutable string slice, use the -str::from_utf8_mut function.

-

Examples

-

Basic usage:

- -
-let mut s = String::from("Hello");
-let bytes = unsafe { s.as_bytes_mut() };
-
-assert_eq!(b"Hello", bytes);Run
-

Mutability:

- -
-let mut s = String::from("🗻∈🌏");
-
-unsafe {
-    let bytes = s.as_bytes_mut();
-
-    bytes[0] = 0xF0;
-    bytes[1] = 0x9F;
-    bytes[2] = 0x8D;
-    bytes[3] = 0x94;
-}
-
-assert_eq!("🍔∈🌏", s);Run
-

Converts a string slice to a raw pointer.

-

As string slices are a slice of bytes, the raw pointer points to a -u8. This pointer will be pointing to the first byte of the string -slice.

-

Examples

-

Basic usage:

- -
-let s = "Hello";
-let ptr = s.as_ptr();Run
-

Returns a subslice of str.

-

This is the non-panicking alternative to indexing the str. Returns -None whenever equivalent indexing operation would panic.

-

Examples

-
-let v = String::from("🗻∈🌏");
-
-assert_eq!(Some("🗻"), v.get(0..4));
-
-// indices not on UTF-8 sequence boundaries
-assert!(v.get(1..).is_none());
-assert!(v.get(..8).is_none());
-
-// out of bounds
-assert!(v.get(..42).is_none());Run
-

Returns a mutable subslice of str.

-

This is the non-panicking alternative to indexing the str. Returns -None whenever equivalent indexing operation would panic.

-

Examples

-
-let mut v = String::from("hello");
-// correct length
-assert!(v.get_mut(0..5).is_some());
-// out of bounds
-assert!(v.get_mut(..42).is_none());
-assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v));
-
-assert_eq!("hello", v);
-{
-    let s = v.get_mut(0..2);
-    let s = s.map(|s| {
-        s.make_ascii_uppercase();
-        &*s
-    });
-    assert_eq!(Some("HE"), s);
-}
-assert_eq!("HEllo", v);Run
-

Returns a unchecked subslice of str.

-

This is the unchecked alternative to indexing the str.

-

Safety

-

Callers of this function are responsible that these preconditions are -satisfied:

-
    -
  • The starting index must come before the ending index;
  • -
  • Indexes must be within bounds of the original slice;
  • -
  • Indexes must lie on UTF-8 sequence boundaries.
  • -
-

Failing that, the returned string slice may reference invalid memory or -violate the invariants communicated by the str type.

-

Examples

-
-let v = "🗻∈🌏";
-unsafe {
-    assert_eq!("🗻", v.get_unchecked(0..4));
-    assert_eq!("∈", v.get_unchecked(4..7));
-    assert_eq!("🌏", v.get_unchecked(7..11));
-}Run
-

Returns a mutable, unchecked subslice of str.

-

This is the unchecked alternative to indexing the str.

-

Safety

-

Callers of this function are responsible that these preconditions are -satisfied:

-
    -
  • The starting index must come before the ending index;
  • -
  • Indexes must be within bounds of the original slice;
  • -
  • Indexes must lie on UTF-8 sequence boundaries.
  • -
-

Failing that, the returned string slice may reference invalid memory or -violate the invariants communicated by the str type.

-

Examples

-
-let mut v = String::from("🗻∈🌏");
-unsafe {
-    assert_eq!("🗻", v.get_unchecked_mut(0..4));
-    assert_eq!("∈", v.get_unchecked_mut(4..7));
-    assert_eq!("🌏", v.get_unchecked_mut(7..11));
-}Run
-

Deprecated since 1.29.0

: use get_unchecked(begin..end) instead

-

Creates a string slice from another string slice, bypassing safety -checks.

-

This is generally not recommended, use with caution! For a safe -alternative see str and Index.

-

This new slice goes from begin to end, including begin but -excluding end.

-

To get a mutable string slice instead, see the -slice_mut_unchecked method.

-

Safety

-

Callers of this function are responsible that three preconditions are -satisfied:

-
    -
  • begin must come before end.
  • -
  • begin and end must be byte positions within the string slice.
  • -
  • begin and end must lie on UTF-8 sequence boundaries.
  • -
-

Examples

-

Basic usage:

- -
-let s = "Löwe 老虎 Léopard";
-
-unsafe {
-    assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
-}
-
-let s = "Hello, world!";
-
-unsafe {
-    assert_eq!("world", s.slice_unchecked(7, 12));
-}Run
-

Deprecated since 1.29.0

: use get_unchecked_mut(begin..end) instead

-

Creates a string slice from another string slice, bypassing safety -checks. -This is generally not recommended, use with caution! For a safe -alternative see str and IndexMut.

-

This new slice goes from begin to end, including begin but -excluding end.

-

To get an immutable string slice instead, see the -slice_unchecked method.

-

Safety

-

Callers of this function are responsible that three preconditions are -satisfied:

-
    -
  • begin must come before end.
  • -
  • begin and end must be byte positions within the string slice.
  • -
  • begin and end must lie on UTF-8 sequence boundaries.
  • -
-

Divide one string slice into two at an index.

-

The argument, mid, should be a byte offset from the start of the -string. It must also be on the boundary of a UTF-8 code point.

-

The two slices returned go from the start of the string slice to mid, -and from mid to the end of the string slice.

-

To get mutable string slices instead, see the split_at_mut -method.

-

Panics

-

Panics if mid is not on a UTF-8 code point boundary, or if it is -beyond the last code point of the string slice.

-

Examples

-

Basic usage:

- -
-let s = "Per Martin-Löf";
-
-let (first, last) = s.split_at(3);
-
-assert_eq!("Per", first);
-assert_eq!(" Martin-Löf", last);Run
-

Divide one mutable string slice into two at an index.

-

The argument, mid, should be a byte offset from the start of the -string. It must also be on the boundary of a UTF-8 code point.

-

The two slices returned go from the start of the string slice to mid, -and from mid to the end of the string slice.

-

To get immutable string slices instead, see the split_at method.

-

Panics

-

Panics if mid is not on a UTF-8 code point boundary, or if it is -beyond the last code point of the string slice.

-

Examples

-

Basic usage:

- -
-let mut s = "Per Martin-Löf".to_string();
-{
-    let (first, last) = s.split_at_mut(3);
-    first.make_ascii_uppercase();
-    assert_eq!("PER", first);
-    assert_eq!(" Martin-Löf", last);
-}
-assert_eq!("PER Martin-Löf", s);Run
-

Important traits for Chars<'a>

Returns an iterator over the chars of a string slice.

-

As a string slice consists of valid UTF-8, we can iterate through a -string slice by char. This method returns such an iterator.

-

It's important to remember that char represents a Unicode Scalar -Value, and may not match your idea of what a 'character' is. Iteration -over grapheme clusters may be what you actually want.

-

Examples

-

Basic usage:

- -
-let word = "goodbye";
-
-let count = word.chars().count();
-assert_eq!(7, count);
-
-let mut chars = word.chars();
-
-assert_eq!(Some('g'), chars.next());
-assert_eq!(Some('o'), chars.next());
-assert_eq!(Some('o'), chars.next());
-assert_eq!(Some('d'), chars.next());
-assert_eq!(Some('b'), chars.next());
-assert_eq!(Some('y'), chars.next());
-assert_eq!(Some('e'), chars.next());
-
-assert_eq!(None, chars.next());Run
-

Remember, chars may not match your human intuition about characters:

- -
-let y = "y̆";
-
-let mut chars = y.chars();
-
-assert_eq!(Some('y'), chars.next()); // not 'y̆'
-assert_eq!(Some('\u{0306}'), chars.next());
-
-assert_eq!(None, chars.next());Run
-

Important traits for CharIndices<'a>

Returns an iterator over the chars of a string slice, and their -positions.

-

As a string slice consists of valid UTF-8, we can iterate through a -string slice by char. This method returns an iterator of both -these chars, as well as their byte positions.

-

The iterator yields tuples. The position is first, the char is -second.

-

Examples

-

Basic usage:

- -
-let word = "goodbye";
-
-let count = word.char_indices().count();
-assert_eq!(7, count);
-
-let mut char_indices = word.char_indices();
-
-assert_eq!(Some((0, 'g')), char_indices.next());
-assert_eq!(Some((1, 'o')), char_indices.next());
-assert_eq!(Some((2, 'o')), char_indices.next());
-assert_eq!(Some((3, 'd')), char_indices.next());
-assert_eq!(Some((4, 'b')), char_indices.next());
-assert_eq!(Some((5, 'y')), char_indices.next());
-assert_eq!(Some((6, 'e')), char_indices.next());
-
-assert_eq!(None, char_indices.next());Run
-

Remember, chars may not match your human intuition about characters:

- -
-let yes = "y̆es";
-
-let mut char_indices = yes.char_indices();
-
-assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
-assert_eq!(Some((1, '\u{0306}')), char_indices.next());
-
-// note the 3 here - the last character took up two bytes
-assert_eq!(Some((3, 'e')), char_indices.next());
-assert_eq!(Some((4, 's')), char_indices.next());
-
-assert_eq!(None, char_indices.next());Run
-

Important traits for Bytes<'a>

An iterator over the bytes of a string slice.

-

As a string slice consists of a sequence of bytes, we can iterate -through a string slice by byte. This method returns such an iterator.

-

Examples

-

Basic usage:

- -
-let mut bytes = "bors".bytes();
-
-assert_eq!(Some(b'b'), bytes.next());
-assert_eq!(Some(b'o'), bytes.next());
-assert_eq!(Some(b'r'), bytes.next());
-assert_eq!(Some(b's'), bytes.next());
-
-assert_eq!(None, bytes.next());Run
-

Important traits for SplitWhitespace<'a>

Split a string slice by whitespace.

-

The iterator returned will return string slices that are sub-slices of -the original string slice, separated by any amount of whitespace.

-

'Whitespace' is defined according to the terms of the Unicode Derived -Core Property White_Space. If you only want to split on ASCII whitespace -instead, use split_ascii_whitespace.

-

Examples

-

Basic usage:

- -
-let mut iter = "A few words".split_whitespace();
-
-assert_eq!(Some("A"), iter.next());
-assert_eq!(Some("few"), iter.next());
-assert_eq!(Some("words"), iter.next());
-
-assert_eq!(None, iter.next());Run
-

All kinds of whitespace are considered:

- -
-let mut iter = " Mary   had\ta\u{2009}little  \n\t lamb".split_whitespace();
-assert_eq!(Some("Mary"), iter.next());
-assert_eq!(Some("had"), iter.next());
-assert_eq!(Some("a"), iter.next());
-assert_eq!(Some("little"), iter.next());
-assert_eq!(Some("lamb"), iter.next());
-
-assert_eq!(None, iter.next());Run
-

Important traits for SplitAsciiWhitespace<'a>

🔬 This is a nightly-only experimental API. (split_ascii_whitespace #48656)

Split a string slice by ASCII whitespace.

-

The iterator returned will return string slices that are sub-slices of -the original string slice, separated by any amount of ASCII whitespace.

-

To split by Unicode Whitespace instead, use split_whitespace.

-

Examples

-

Basic usage:

- -
-#![feature(split_ascii_whitespace)]
-let mut iter = "A few words".split_ascii_whitespace();
-
-assert_eq!(Some("A"), iter.next());
-assert_eq!(Some("few"), iter.next());
-assert_eq!(Some("words"), iter.next());
-
-assert_eq!(None, iter.next());Run
-

All kinds of ASCII whitespace are considered:

- -
-let mut iter = " Mary   had\ta little  \n\t lamb".split_whitespace();
-assert_eq!(Some("Mary"), iter.next());
-assert_eq!(Some("had"), iter.next());
-assert_eq!(Some("a"), iter.next());
-assert_eq!(Some("little"), iter.next());
-assert_eq!(Some("lamb"), iter.next());
-
-assert_eq!(None, iter.next());Run
-

Important traits for Lines<'a>

An iterator over the lines of a string, as string slices.

-

Lines are ended with either a newline (\n) or a carriage return with -a line feed (\r\n).

-

The final line ending is optional.

-

Examples

-

Basic usage:

- -
-let text = "foo\r\nbar\n\nbaz\n";
-let mut lines = text.lines();
-
-assert_eq!(Some("foo"), lines.next());
-assert_eq!(Some("bar"), lines.next());
-assert_eq!(Some(""), lines.next());
-assert_eq!(Some("baz"), lines.next());
-
-assert_eq!(None, lines.next());Run
-

The final line ending isn't required:

- -
-let text = "foo\nbar\n\r\nbaz";
-let mut lines = text.lines();
-
-assert_eq!(Some("foo"), lines.next());
-assert_eq!(Some("bar"), lines.next());
-assert_eq!(Some(""), lines.next());
-assert_eq!(Some("baz"), lines.next());
-
-assert_eq!(None, lines.next());Run
-

Important traits for LinesAny<'a>

Deprecated since 1.4.0

: use lines() instead now

-

An iterator over the lines of a string.

-

Important traits for EncodeUtf16<'a>

Returns an iterator of u16 over the string encoded as UTF-16.

-

Examples

-

Basic usage:

- -
-let text = "Zażółć gęślą jaźń";
-
-let utf8_len = text.len();
-let utf16_len = text.encode_utf16().count();
-
-assert!(utf16_len <= utf8_len);Run
-

Returns true if the given pattern matches a sub-slice of -this string slice.

-

Returns false if it does not.

-

Examples

-

Basic usage:

- -
-let bananas = "bananas";
-
-assert!(bananas.contains("nana"));
-assert!(!bananas.contains("apples"));Run
-

Returns true if the given pattern matches a prefix of this -string slice.

-

Returns false if it does not.

-

Examples

-

Basic usage:

- -
-let bananas = "bananas";
-
-assert!(bananas.starts_with("bana"));
-assert!(!bananas.starts_with("nana"));Run
-

Returns true if the given pattern matches a suffix of this -string slice.

-

Returns false if it does not.

-

Examples

-

Basic usage:

- -
-let bananas = "bananas";
-
-assert!(bananas.ends_with("anas"));
-assert!(!bananas.ends_with("nana"));Run
-

Returns the byte index of the first character of this string slice that -matches the pattern.

-

Returns None if the pattern doesn't match.

-

The pattern can be a &str, char, or a closure that determines if -a character matches.

-

Examples

-

Simple patterns:

- -
-let s = "Löwe 老虎 Léopard";
-
-assert_eq!(s.find('L'), Some(0));
-assert_eq!(s.find('é'), Some(14));
-assert_eq!(s.find("Léopard"), Some(13));Run
-

More complex patterns using point-free style and closures:

- -
-let s = "Löwe 老虎 Léopard";
-
-assert_eq!(s.find(char::is_whitespace), Some(5));
-assert_eq!(s.find(char::is_lowercase), Some(1));
-assert_eq!(s.find(|c: char| c.is_whitespace() || c.is_lowercase()), Some(1));
-assert_eq!(s.find(|c: char| (c < 'o') && (c > 'a')), Some(4));Run
-

Not finding the pattern:

- -
-let s = "Löwe 老虎 Léopard";
-let x: &[_] = &['1', '2'];
-
-assert_eq!(s.find(x), None);Run
-

Returns the byte index of the last character of this string slice that -matches the pattern.

-

Returns None if the pattern doesn't match.

-

The pattern can be a &str, char, or a closure that determines if -a character matches.

-

Examples

-

Simple patterns:

- -
-let s = "Löwe 老虎 Léopard";
-
-assert_eq!(s.rfind('L'), Some(13));
-assert_eq!(s.rfind('é'), Some(14));Run
-

More complex patterns with closures:

- -
-let s = "Löwe 老虎 Léopard";
-
-assert_eq!(s.rfind(char::is_whitespace), Some(12));
-assert_eq!(s.rfind(char::is_lowercase), Some(20));Run
-

Not finding the pattern:

- -
-let s = "Löwe 老虎 Léopard";
-let x: &[_] = &['1', '2'];
-
-assert_eq!(s.rfind(x), None);Run
-

Important traits for Split<'a, P>

An iterator over substrings of this string slice, separated by -characters matched by a pattern.

-

The pattern can be a &str, char, or a closure that determines the -split.

-

Iterator behavior

-

The returned iterator will be a DoubleEndedIterator if the pattern -allows a reverse search and forward/reverse search yields the same -elements. This is true for, eg, char but not for &str.

-

If the pattern allows a reverse search but its results might differ -from a forward search, the rsplit method can be used.

-

Examples

-

Simple patterns:

- -
-let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
-assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
-
-let v: Vec<&str> = "".split('X').collect();
-assert_eq!(v, [""]);
-
-let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
-assert_eq!(v, ["lion", "", "tiger", "leopard"]);
-
-let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
-assert_eq!(v, ["lion", "tiger", "leopard"]);
-
-let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
-assert_eq!(v, ["abc", "def", "ghi"]);
-
-let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
-assert_eq!(v, ["lion", "tiger", "leopard"]);Run
-

A more complex pattern, using a closure:

- -
-let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
-assert_eq!(v, ["abc", "def", "ghi"]);Run
-

If a string contains multiple contiguous separators, you will end up -with empty strings in the output:

- -
-let x = "||||a||b|c".to_string();
-let d: Vec<_> = x.split('|').collect();
-
-assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);Run
-

Contiguous separators are separated by the empty string.

- -
-let x = "(///)".to_string();
-let d: Vec<_> = x.split('/').collect();
-
-assert_eq!(d, &["(", "", "", ")"]);Run
-

Separators at the start or end of a string are neighbored -by empty strings.

- -
-let d: Vec<_> = "010".split("0").collect();
-assert_eq!(d, &["", "1", ""]);Run
-

When the empty string is used as a separator, it separates -every character in the string, along with the beginning -and end of the string.

- -
-let f: Vec<_> = "rust".split("").collect();
-assert_eq!(f, &["", "r", "u", "s", "t", ""]);Run
-

Contiguous separators can lead to possibly surprising behavior -when whitespace is used as the separator. This code is correct:

- -
-let x = "    a  b c".to_string();
-let d: Vec<_> = x.split(' ').collect();
-
-assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);Run
-

It does not give you:

- -
This example is not tested
-assert_eq!(d, &["a", "b", "c"]);Run
-

Use split_whitespace for this behavior.

-

Important traits for RSplit<'a, P>

An iterator over substrings of the given string slice, separated by -characters matched by a pattern and yielded in reverse order.

-

The pattern can be a &str, char, or a closure that determines the -split.

-

Iterator behavior

-

The returned iterator requires that the pattern supports a reverse -search, and it will be a DoubleEndedIterator if a forward/reverse -search yields the same elements.

-

For iterating from the front, the split method can be used.

-

Examples

-

Simple patterns:

- -
-let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
-assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
-
-let v: Vec<&str> = "".rsplit('X').collect();
-assert_eq!(v, [""]);
-
-let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
-assert_eq!(v, ["leopard", "tiger", "", "lion"]);
-
-let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
-assert_eq!(v, ["leopard", "tiger", "lion"]);Run
-

A more complex pattern, using a closure:

- -
-let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
-assert_eq!(v, ["ghi", "def", "abc"]);Run
-

Important traits for SplitTerminator<'a, P>

An iterator over substrings of the given string slice, separated by -characters matched by a pattern.

-

The pattern can be a &str, char, or a closure that determines the -split.

-

Equivalent to split, except that the trailing substring -is skipped if empty.

-

This method can be used for string data that is terminated, -rather than separated by a pattern.

-

Iterator behavior

-

The returned iterator will be a DoubleEndedIterator if the pattern -allows a reverse search and forward/reverse search yields the same -elements. This is true for, eg, char but not for &str.

-

If the pattern allows a reverse search but its results might differ -from a forward search, the rsplit_terminator method can be used.

-

Examples

-

Basic usage:

- -
-let v: Vec<&str> = "A.B.".split_terminator('.').collect();
-assert_eq!(v, ["A", "B"]);
-
-let v: Vec<&str> = "A..B..".split_terminator(".").collect();
-assert_eq!(v, ["A", "", "B", ""]);Run
-

Important traits for RSplitTerminator<'a, P>

An iterator over substrings of self, separated by characters -matched by a pattern and yielded in reverse order.

-

The pattern can be a simple &str, char, or a closure that -determines the split. -Additional libraries might provide more complex patterns like -regular expressions.

-

Equivalent to split, except that the trailing substring is -skipped if empty.

-

This method can be used for string data that is terminated, -rather than separated by a pattern.

-

Iterator behavior

-

The returned iterator requires that the pattern supports a -reverse search, and it will be double ended if a forward/reverse -search yields the same elements.

-

For iterating from the front, the split_terminator method can be -used.

-

Examples

-
-let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
-assert_eq!(v, ["B", "A"]);
-
-let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
-assert_eq!(v, ["", "B", "", "A"]);Run
-

Important traits for SplitN<'a, P>

An iterator over substrings of the given string slice, separated by a -pattern, restricted to returning at most n items.

-

If n substrings are returned, the last substring (the nth substring) -will contain the remainder of the string.

-

The pattern can be a &str, char, or a closure that determines the -split.

-

Iterator behavior

-

The returned iterator will not be double ended, because it is -not efficient to support.

-

If the pattern allows a reverse search, the rsplitn method can be -used.

-

Examples

-

Simple patterns:

- -
-let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
-assert_eq!(v, ["Mary", "had", "a little lambda"]);
-
-let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
-assert_eq!(v, ["lion", "", "tigerXleopard"]);
-
-let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
-assert_eq!(v, ["abcXdef"]);
-
-let v: Vec<&str> = "".splitn(1, 'X').collect();
-assert_eq!(v, [""]);Run
-

A more complex pattern, using a closure:

- -
-let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
-assert_eq!(v, ["abc", "defXghi"]);Run
-

Important traits for RSplitN<'a, P>

An iterator over substrings of this string slice, separated by a -pattern, starting from the end of the string, restricted to returning -at most n items.

-

If n substrings are returned, the last substring (the nth substring) -will contain the remainder of the string.

-

The pattern can be a &str, char, or a closure that -determines the split.

-

Iterator behavior

-

The returned iterator will not be double ended, because it is not -efficient to support.

-

For splitting from the front, the splitn method can be used.

-

Examples

-

Simple patterns:

- -
-let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
-assert_eq!(v, ["lamb", "little", "Mary had a"]);
-
-let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
-assert_eq!(v, ["leopard", "tiger", "lionX"]);
-
-let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
-assert_eq!(v, ["leopard", "lion::tiger"]);Run
-

A more complex pattern, using a closure:

- -
-let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
-assert_eq!(v, ["ghi", "abc1def"]);Run
-

Important traits for Matches<'a, P>

An iterator over the disjoint matches of a pattern within the given string -slice.

-

The pattern can be a &str, char, or a closure that -determines if a character matches.

-

Iterator behavior

-

The returned iterator will be a DoubleEndedIterator if the pattern -allows a reverse search and forward/reverse search yields the same -elements. This is true for, eg, char but not for &str.

-

If the pattern allows a reverse search but its results might differ -from a forward search, the rmatches method can be used.

-

Examples

-

Basic usage:

- -
-let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
-assert_eq!(v, ["abc", "abc", "abc"]);
-
-let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
-assert_eq!(v, ["1", "2", "3"]);Run
-

Important traits for RMatches<'a, P>

An iterator over the disjoint matches of a pattern within this string slice, -yielded in reverse order.

-

The pattern can be a &str, char, or a closure that determines if -a character matches.

-

Iterator behavior

-

The returned iterator requires that the pattern supports a reverse -search, and it will be a DoubleEndedIterator if a forward/reverse -search yields the same elements.

-

For iterating from the front, the matches method can be used.

-

Examples

-

Basic usage:

- -
-let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
-assert_eq!(v, ["abc", "abc", "abc"]);
-
-let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
-assert_eq!(v, ["3", "2", "1"]);Run
-

Important traits for MatchIndices<'a, P>

An iterator over the disjoint matches of a pattern within this string -slice as well as the index that the match starts at.

-

For matches of pat within self that overlap, only the indices -corresponding to the first match are returned.

-

The pattern can be a &str, char, or a closure that determines -if a character matches.

-

Iterator behavior

-

The returned iterator will be a DoubleEndedIterator if the pattern -allows a reverse search and forward/reverse search yields the same -elements. This is true for, eg, char but not for &str.

-

If the pattern allows a reverse search but its results might differ -from a forward search, the rmatch_indices method can be used.

-

Examples

-

Basic usage:

- -
-let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
-assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
-
-let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
-assert_eq!(v, [(1, "abc"), (4, "abc")]);
-
-let v: Vec<_> = "ababa".match_indices("aba").collect();
-assert_eq!(v, [(0, "aba")]); // only the first `aba`Run
-

Important traits for RMatchIndices<'a, P>

An iterator over the disjoint matches of a pattern within self, -yielded in reverse order along with the index of the match.

-

For matches of pat within self that overlap, only the indices -corresponding to the last match are returned.

-

The pattern can be a &str, char, or a closure that determines if a -character matches.

-

Iterator behavior

-

The returned iterator requires that the pattern supports a reverse -search, and it will be a DoubleEndedIterator if a forward/reverse -search yields the same elements.

-

For iterating from the front, the match_indices method can be used.

-

Examples

-

Basic usage:

- -
-let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
-assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
-
-let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
-assert_eq!(v, [(4, "abc"), (1, "abc")]);
-
-let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
-assert_eq!(v, [(2, "aba")]); // only the last `aba`Run
-

Returns a string slice with leading and trailing whitespace removed.

-

'Whitespace' is defined according to the terms of the Unicode Derived -Core Property White_Space.

-

Examples

-

Basic usage:

- -
-let s = " Hello\tworld\t";
-
-assert_eq!("Hello\tworld", s.trim());Run
-

Returns a string slice with leading whitespace removed.

-

'Whitespace' is defined according to the terms of the Unicode Derived -Core Property White_Space.

-

Text directionality

-

A string is a sequence of bytes. 'Left' in this context means the first -position of that byte string; for a language like Arabic or Hebrew -which are 'right to left' rather than 'left to right', this will be -the right side, not the left.

-

Examples

-

Basic usage:

- -
-let s = " Hello\tworld\t";
-
-assert_eq!("Hello\tworld\t", s.trim_left());Run
-

Directionality:

- -
-let s = "  English";
-assert!(Some('E') == s.trim_left().chars().next());
-
-let s = "  עברית";
-assert!(Some('ע') == s.trim_left().chars().next());Run
-

Returns a string slice with trailing whitespace removed.

-

'Whitespace' is defined according to the terms of the Unicode Derived -Core Property White_Space.

-

Text directionality

-

A string is a sequence of bytes. 'Right' in this context means the last -position of that byte string; for a language like Arabic or Hebrew -which are 'right to left' rather than 'left to right', this will be -the left side, not the right.

-

Examples

-

Basic usage:

- -
-let s = " Hello\tworld\t";
-
-assert_eq!(" Hello\tworld", s.trim_right());Run
-

Directionality:

- -
-let s = "English  ";
-assert!(Some('h') == s.trim_right().chars().rev().next());
-
-let s = "עברית  ";
-assert!(Some('ת') == s.trim_right().chars().rev().next());Run
-

Returns a string slice with all prefixes and suffixes that match a -pattern repeatedly removed.

-

The pattern can be a char or a closure that determines if a -character matches.

-

Examples

-

Simple patterns:

- -
-assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
-assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
-
-let x: &[_] = &['1', '2'];
-assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");Run
-

A more complex pattern, using a closure:

- -
-assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");Run
-

Returns a string slice with all prefixes that match a pattern -repeatedly removed.

-

The pattern can be a &str, char, or a closure that determines if -a character matches.

-

Text directionality

-

A string is a sequence of bytes. 'Left' in this context means the first -position of that byte string; for a language like Arabic or Hebrew -which are 'right to left' rather than 'left to right', this will be -the right side, not the left.

-

Examples

-

Basic usage:

- -
-assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
-assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
-
-let x: &[_] = &['1', '2'];
-assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");Run
-

Returns a string slice with all suffixes that match a pattern -repeatedly removed.

-

The pattern can be a &str, char, or a closure that -determines if a character matches.

-

Text directionality

-

A string is a sequence of bytes. 'Right' in this context means the last -position of that byte string; for a language like Arabic or Hebrew -which are 'right to left' rather than 'left to right', this will be -the left side, not the right.

-

Examples

-

Simple patterns:

- -
-assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
-assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
-
-let x: &[_] = &['1', '2'];
-assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");Run
-

A more complex pattern, using a closure:

- -
-assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo");Run
-

Parses this string slice into another type.

-

Because parse is so general, it can cause problems with type -inference. As such, parse is one of the few times you'll see -the syntax affectionately known as the 'turbofish': ::<>. This -helps the inference algorithm understand specifically which type -you're trying to parse into.

-

parse can parse any type that implements the FromStr trait.

-

Errors

-

Will return Err if it's not possible to parse this string slice into -the desired type.

-

Examples

-

Basic usage

- -
-let four: u32 = "4".parse().unwrap();
-
-assert_eq!(4, four);Run
-

Using the 'turbofish' instead of annotating four:

- -
-let four = "4".parse::<u32>();
-
-assert_eq!(Ok(4), four);Run
-

Failing to parse:

- -
-let nope = "j".parse::<u32>();
-
-assert!(nope.is_err());Run
-

Checks if all characters in this string are within the ASCII range.

-

Examples

-
-let ascii = "hello!\n";
-let non_ascii = "Grüße, Jürgen ❤";
-
-assert!(ascii.is_ascii());
-assert!(!non_ascii.is_ascii());Run
-

Checks that two strings are an ASCII case-insensitive match.

-

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), -but without allocating and copying temporaries.

-

Examples

-
-assert!("Ferris".eq_ignore_ascii_case("FERRIS"));
-assert!("Ferrös".eq_ignore_ascii_case("FERRöS"));
-assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));Run
-

Converts this string to its ASCII upper case equivalent in-place.

-

ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', -but non-ASCII letters are unchanged.

-

To return a new uppercased value without modifying the existing one, use -to_ascii_uppercase.

-

Converts this string to its ASCII lower case equivalent in-place.

-

ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', -but non-ASCII letters are unchanged.

-

To return a new lowercased value without modifying the existing one, use -to_ascii_lowercase.

-

Replaces all matches of a pattern with another string.

-

replace creates a new String, and copies the data from this string slice into it. -While doing so, it attempts to find matches of a pattern. If it finds any, it -replaces them with the replacement string slice.

-

Examples

-

Basic usage:

- -
-let s = "this is old";
-
-assert_eq!("this is new", s.replace("old", "new"));Run
-

When the pattern doesn't match:

- -
-let s = "this is old";
-assert_eq!(s, s.replace("cookie monster", "little lamb"));Run
-

Replaces first N matches of a pattern with another string.

-

replacen creates a new String, and copies the data from this string slice into it. -While doing so, it attempts to find matches of a pattern. If it finds any, it -replaces them with the replacement string slice at most count times.

-

Examples

-

Basic usage:

- -
-let s = "foo foo 123 foo";
-assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
-assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
-assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));Run
-

When the pattern doesn't match:

- -
-let s = "this is old";
-assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));Run
-

Returns the lowercase equivalent of this string slice, as a new String.

-

'Lowercase' is defined according to the terms of the Unicode Derived Core Property -Lowercase.

-

Since some characters can expand into multiple characters when changing -the case, this function returns a String instead of modifying the -parameter in-place.

-

Examples

-

Basic usage:

- -
-let s = "HELLO";
-
-assert_eq!("hello", s.to_lowercase());Run
-

A tricky example, with sigma:

- -
-let sigma = "Σ";
-
-assert_eq!("σ", sigma.to_lowercase());
-
-// but at the end of a word, it's ς, not σ:
-let odysseus = "ὈΔΥΣΣΕΎΣ";
-
-assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());Run
-

Languages without case are not changed:

- -
-let new_year = "农历新年";
-
-assert_eq!(new_year, new_year.to_lowercase());Run
-

Returns the uppercase equivalent of this string slice, as a new String.

-

'Uppercase' is defined according to the terms of the Unicode Derived Core Property -Uppercase.

-

Since some characters can expand into multiple characters when changing -the case, this function returns a String instead of modifying the -parameter in-place.

-

Examples

-

Basic usage:

- -
-let s = "hello";
-
-assert_eq!("HELLO", s.to_uppercase());Run
-

Scripts without case are not changed:

- -
-let new_year = "农历新年";
-
-assert_eq!(new_year, new_year.to_uppercase());Run
-

🔬 This is a nightly-only experimental API. (str_escape #27791)

return type may change to be an iterator

-

Escapes each char in s with char::escape_debug.

-

Note: only extended grapheme codepoints that begin the string will be -escaped.

-

🔬 This is a nightly-only experimental API. (str_escape #27791)

return type may change to be an iterator

-

Escapes each char in s with char::escape_default.

-

🔬 This is a nightly-only experimental API. (str_escape #27791)

return type may change to be an iterator

-

Escapes each char in s with char::escape_unicode.

-

Create a String by repeating a string n times.

-

Examples

-

Basic usage:

- -
-assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));Run
-

Returns a copy of this string where each character is mapped to its -ASCII upper case equivalent.

-

ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', -but non-ASCII letters are unchanged.

-

To uppercase the value in-place, use make_ascii_uppercase.

-

To uppercase ASCII characters in addition to non-ASCII characters, use -to_uppercase.

-

Examples

-
-let s = "Grüße, Jürgen ❤";
-
-assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());Run
-

Returns a copy of this string where each character is mapped to its -ASCII lower case equivalent.

-

ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', -but non-ASCII letters are unchanged.

-

To lowercase the value in-place, use make_ascii_lowercase.

-

To lowercase ASCII characters in addition to non-ASCII characters, use -to_lowercase.

-

Examples

-
-let s = "Grüße, Jürgen ❤";
-
-assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());Run
-

Trait Implementations

impl Eq for String
[src]

impl<'a> FromIterator<&'a str> for String
[src]

Creates a value from an iterator. Read more

-

impl FromIterator<String> for String
1.4.0
[src]

Creates a value from an iterator. Read more

-

impl FromIterator<char> for String
[src]

Creates a value from an iterator. Read more

-

impl<'a> FromIterator<Cow<'a, str>> for String
1.19.0
[src]

Creates a value from an iterator. Read more

-

impl<'a> FromIterator<String> for Cow<'a, str>
1.12.0
[src]

Creates a value from an iterator. Read more

-

impl<'a> FromIterator<&'a char> for String
1.17.0
[src]

Creates a value from an iterator. Read more

-

impl Ord for String
[src]

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

impl FromStr for String
[src]

-

The associated error which can be returned from parsing.

-

Parses a string s to return a value of this type. Read more

-

impl Clone for String
[src]

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

impl Debug for String
[src]

Formats the value using the given formatter. Read more

-

impl Display for String
[src]

Formats the value using the given formatter. Read more

-

impl Extend<char> for String
[src]

Extends a collection with the contents of an iterator. Read more

-

impl<'a> Extend<&'a char> for String
1.2.0
[src]

Extends a collection with the contents of an iterator. Read more

-

impl Extend<String> for String
1.4.0
[src]

Extends a collection with the contents of an iterator. Read more

-

impl<'a> Extend<&'a str> for String
[src]

Extends a collection with the contents of an iterator. Read more

-

impl<'a> Extend<Cow<'a, str>> for String
1.19.0
[src]

Extends a collection with the contents of an iterator. Read more

-

impl<'a, 'b> Pattern<'a> for &'b String
[src]

A convenience impl that delegates to the impl for &str

-

-
🔬 This is a nightly-only experimental API. (pattern #27721)

API not fully fleshed out and ready to be stabilized

-

Associated searcher for this pattern

-

🔬 This is a nightly-only experimental API. (pattern #27721)

API not fully fleshed out and ready to be stabilized

-

Constructs the associated searcher from self and the haystack to search in. Read more

-

🔬 This is a nightly-only experimental API. (pattern #27721)

API not fully fleshed out and ready to be stabilized

-

Checks whether the pattern matches anywhere in the haystack

-

🔬 This is a nightly-only experimental API. (pattern #27721)

API not fully fleshed out and ready to be stabilized

-

Checks whether the pattern matches at the front of the haystack

-

🔬 This is a nightly-only experimental API. (pattern #27721)

API not fully fleshed out and ready to be stabilized

-

Checks whether the pattern matches at the back of the haystack

-

impl AsRef<str> for String
[src]

Performs the conversion.

-

impl AsRef<[u8]> for String
[src]

Important traits for &'a [u8]

Performs the conversion.

-

impl Deref for String
[src]

-

The resulting type after dereferencing.

-

Dereferences the value.

-

impl<'a> Add<&'a str> for String
[src]

Implements the + operator for concatenating two strings.

-

This consumes the String on the left-hand side and re-uses its buffer (growing it if -necessary). This is done to avoid allocating a new String and copying the entire contents on -every operation, which would lead to O(n^2) running time when building an n-byte string by -repeated concatenation.

-

The string on the right-hand side is only borrowed; its contents are copied into the returned -String.

-

Examples

-

Concatenating two Strings takes the first by value and borrows the second:

- -
-let a = String::from("hello");
-let b = String::from(" world");
-let c = a + &b;
-// `a` is moved and can no longer be used here.Run
-

If you want to keep using the first String, you can clone it and append to the clone instead:

- -
-let a = String::from("hello");
-let b = String::from(" world");
-let c = a.clone() + &b;
-// `a` is still valid here.Run
-

Concatenating &str slices can be done by converting the first to a String:

- -
-let a = "hello";
-let b = " world";
-let c = a.to_string() + b;Run
-

-

The resulting type after applying the + operator.

-

Performs the + operation.

-

impl Index<RangeFull> for String
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Index<Range<usize>> for String
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Index<RangeInclusive<usize>> for String
1.26.0
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Index<RangeFrom<usize>> for String
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Index<RangeToInclusive<usize>> for String
1.26.0
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Index<RangeTo<usize>> for String
[src]

-

The returned type after indexing.

-

Performs the indexing (container[index]) operation.

-

impl Borrow<str> for String
[src]

Immutably borrows from an owned value. Read more

-

impl IndexMut<RangeTo<usize>> for String
1.3.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl IndexMut<Range<usize>> for String
1.3.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl IndexMut<RangeToInclusive<usize>> for String
1.26.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl IndexMut<RangeInclusive<usize>> for String
1.26.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl IndexMut<RangeFull> for String
1.3.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl IndexMut<RangeFrom<usize>> for String
1.3.0
[src]

Performs the mutable indexing (container[index]) operation.

-

impl DerefMut for String
1.3.0
[src]

Mutably dereferences the value.

-

impl Default for String
[src]

Creates an empty String.

-

impl<'a, 'b> PartialEq<String> for &'a str
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl<'a, 'b> PartialEq<&'a str> for String
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl<'a, 'b> PartialEq<String> for Cow<'a, str>
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl<'a, 'b> PartialEq<str> for String
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl PartialEq<String> for String
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl<'a, 'b> PartialEq<String> for str
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl<'a, 'b> PartialEq<Cow<'a, str>> for String
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

-

This method tests for !=.

-

impl Write for String
[src]

Writes a slice of bytes into this writer, returning whether the write succeeded. Read more

-

Writes a [char] into this writer, returning whether the write succeeded. Read more

-

Glue for usage of the [write!] macro with implementors of this trait. Read more

-

impl ToString for String
1.17.0
[src]

Converts the given value to a String. Read more

-

impl From<String> for Box<str>
1.20.0
[src]

Important traits for Box<I>

Performs the conversion.

-

impl From<String> for Vec<u8>
1.14.0
[src]

Important traits for Vec<u8>

Performs the conversion.

-

impl From<String> for Arc<str>
1.21.0
[src]

Performs the conversion.

-

impl<'a> From<&'a String> for Cow<'a, str>
1.28.0
[src]

Performs the conversion.

-

impl<'a> From<String> for Cow<'a, str>
[src]

Performs the conversion.

-

impl<'a> From<Cow<'a, str>> for String
1.14.0
[src]

Performs the conversion.

-

impl<'a> From<&'a str> for String
[src]

Performs the conversion.

-

impl From<String> for Rc<str>
1.21.0
[src]

Performs the conversion.

-

impl From<Box<str>> for String
1.18.0
[src]

Performs the conversion.

-

impl Hash for String
[src]

Feeds this value into the given [Hasher]. Read more

-

Feeds a slice of this type into the given [Hasher]. Read more

-

impl PartialOrd<String> for String
[src]

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

-

impl<'a> AddAssign<&'a str> for String
1.12.0
[src]

Implements the += operator for appending to a String.

-

This has the same behavior as the push_str method.

-

Performs the += operation.

-

impl From<String> for Box<Error + Send + Sync>
[src]

Important traits for Box<I>

Performs the conversion.

-

impl From<String> for Box<Error>
1.6.0
[src]

Important traits for Box<I>

Performs the conversion.

-

impl From<String> for OsString
[src]

Performs the conversion.

-

impl AsRef<OsStr> for String
[src]

Performs the conversion.

-

impl ToSocketAddrs for String
1.16.0
[src]

-

Returned iterator over socket addresses which this type may correspond to. Read more

-

Converts this object to an iterator of resolved SocketAddrs. Read more

-

impl From<String> for PathBuf
[src]

Performs the conversion.

-

impl AsRef<Path> for String
[src]

Performs the conversion.

-

Auto Trait Implementations

impl Send for String

impl Sync for String

Blanket Implementations

impl<T, U> TryFrom for T where
    T: From<U>, 
[src]

-
🔬 This is a nightly-only experimental API. (try_from #33417)

The type returned in the event of a conversion error.

-

🔬 This is a nightly-only experimental API. (try_from #33417)

Performs the conversion.

-

impl<T> From for T
[src]

Performs the conversion.

-

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

-
🔬 This is a nightly-only experimental API. (try_from #33417)

The type returned in the event of a conversion error.

-

🔬 This is a nightly-only experimental API. (try_from #33417)

Performs the conversion.

-

impl<T, U> Into for T where
    U: From<T>, 
[src]

Performs the conversion.

-

impl<T> Borrow for T where
    T: ?Sized
[src]

Important traits for &'a mut I

Immutably borrows from an owned value. Read more

-

impl<T> BorrowMut for T where
    T: ?Sized
[src]

Important traits for &'a mut I

Mutably borrows from an owned value. Read more

-

impl<T> Any for T where
    T: 'static + ?Sized
[src]

🔬 This is a nightly-only experimental API. (get_type_id #27745)

this method will likely be replaced by an associated static

-

Gets the TypeId of self. Read more

-

impl<T> ToOwned for T where
    T: Clone
[src]

-

Creates owned data from borrowed data, usually by cloning. Read more

-

🔬 This is a nightly-only experimental API. (toowned_clone_into #41263)

recently added

-

Uses borrowed data to replace owned data, usually by cloning. Read more

-

impl<T> ToString for T where
    T: Display + ?Sized
[src]

Converts the given value to a String. Read more

-
diff --git a/examples/get.rs b/examples/get.rs index 9578fc1..6b37684 100644 --- a/examples/get.rs +++ b/examples/get.rs @@ -2,7 +2,11 @@ use wasmedge_http_req::request; fn main() { let mut writer = Vec::new(); //container for body of a response - let res = request::get("https://www.rust-lang.org/learn", &mut writer).unwrap(); + let res = request::get( + "http://doc.rust-lang.org/std/string/index.html", + &mut writer, + ) + .unwrap(); println!("Status: {} {}", res.status_code(), res.reason()); println!("Headers {}", res.headers()); diff --git a/examples/head.rs b/examples/head.rs index 482d918..c96ed66 100644 --- a/examples/head.rs +++ b/examples/head.rs @@ -1,7 +1,7 @@ use wasmedge_http_req::request; fn main() { - let res = request::head("https://www.rust-lang.org/learn").unwrap(); + let res = request::head("http://doc.rust-lang.org/std/string/index.html").unwrap(); println!("Status: {} {}", res.status_code(), res.reason()); println!("{:?}", res.headers()); diff --git a/examples/post.rs b/examples/post.rs index 9fefc90..815f972 100644 --- a/examples/post.rs +++ b/examples/post.rs @@ -2,12 +2,13 @@ use wasmedge_http_req::request; fn main() { let mut writer = Vec::new(); //container for body of a response - const BODY: &[u8; 27] = b"field1=value1&field2=value2"; - // let res = request::post("https://httpbin.org/post", BODY, &mut writer).unwrap(); - // no https , no dns - let res = request::post("http://18.235.124.214/post", BODY, &mut writer).unwrap(); + const BODY: &[u8; 42] = b"{\"field1\" : \"value1\", \"field2\" : \"value2\"}"; + // dns is supported + // tls is not supported + // Use tests/server.py for testing + let res = request::post("http://localhost:1234/post", BODY, &mut writer).unwrap(); println!("Status: {} {}", res.status_code(), res.reason()); println!("Headers {}", res.headers()); - //println!("{}", String::from_utf8_lossy(&writer)); + println!("{}", String::from_utf8_lossy(&writer)); } diff --git a/examples/request_builder_get.rs b/examples/request_builder_get.rs index 68abcdf..716945a 100644 --- a/examples/request_builder_get.rs +++ b/examples/request_builder_get.rs @@ -1,8 +1,8 @@ -use wasmedge_http_req::{request::RequestBuilder, tls, uri::Uri}; -use std::{convert::TryFrom, net::TcpStream}; +// use std::{convert::TryFrom, net::TcpStream}; +// use wasmedge_http_req::{request::RequestBuilder, tls, uri::Uri}; #[cfg(not(tls))] -fn main(){ +fn main() { unimplemented!() } diff --git a/src/chunked.rs b/src/chunked.rs index ffc3e4d..45e0ee3 100644 --- a/src/chunked.rs +++ b/src/chunked.rs @@ -35,11 +35,9 @@ where break; } - if let Ok(_) = self.reader.read_exact(&mut footer) { - if footer != CR_LF { - self.err = Some(error_malformed_chunked_encoding()); - break; - } + if self.reader.read_exact(&mut footer).is_ok() && footer != CR_LF { + self.err = Some(error_malformed_chunked_encoding()); + break; } self.check_end = false; @@ -84,10 +82,7 @@ where } match self.err.as_ref() { - Some(v) => Err(Error::new( - v.kind(), - format!("wrapper by chunked: {}", v.to_string()), - )), + Some(v) => Err(Error::new(v.kind(), format!("wrapper by chunked: {}", v))), None => Ok(consumed), } } @@ -129,7 +124,7 @@ where } fn chunk_header_avaliable(&self) -> bool { - self.reader.buffer().iter().find(|&&c| c == b'\n').is_some() + self.reader.buffer().iter().any(|&c| c == b'\n') } } @@ -142,10 +137,7 @@ fn error_malformed_chunked_encoding() -> Error { } fn is_ascii_space(b: u8) -> bool { - match b { - b' ' | b'\t' | b'\n' | b'\r' => true, - _ => false, - } + matches!(b, b' ' | b'\t' | b'\n' | b'\r') } fn parse_hex_uint(data: Vec) -> Result { @@ -193,7 +185,7 @@ fn remove_chunk_extension(v: &mut Vec) { } fn trim_trailing_whitespace(v: &mut Vec) { - if v.len() == 0 { + if v.is_empty() { return; } diff --git a/src/lib.rs b/src/lib.rs index 61e74e1..284f68c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,5 @@ //!Simple HTTP client with built-in HTTPS support. //!Currently it's in heavy development and may frequently change. -//! -//!## Example -//!Basic GET request -//!``` -//!use http_req::request; -//! -//!fn main() { -//! let mut writer = Vec::new(); //container for body of a response -//! let res = request::get("https://doc.rust-lang.org/", &mut writer).unwrap(); -//! -//! println!("Status: {} {}", res.status_code(), res.reason()); -//!} -//!``` pub mod error; pub mod request; pub mod response; diff --git a/src/request.rs b/src/request.rs index 520172e..d6c836f 100644 --- a/src/request.rs +++ b/src/request.rs @@ -12,10 +12,7 @@ use std::{ time::{Duration, Instant}, }; -#[cfg(feature = "std")] -use std::net::{Shutdown, TcpStream}; -#[cfg(not(feature = "std"))] -use wasmedge_wasi_socket::{Shutdown, TcpStream}; +use wasmedge_wasi_socket::{TcpStream, WasiAddrinfo}; const CR_LF: &str = "\r\n"; const BUF_SIZE: usize = 8 * 1024; @@ -88,7 +85,7 @@ where let mut buf = vec![0u8; num_bytes]; reader.read_exact(&mut buf)?; - writer.write_all(&mut buf) + writer.write_all(&buf) } ///Reads data from `reader` and checks for specified `val`ue. When data contains specified value @@ -615,7 +612,7 @@ impl<'a> Request<'a> { ///let response = Request::new(&uri).send(&mut writer).unwrap();; ///``` pub fn new(uri: &'a Uri) -> Request<'a> { - let mut builder = RequestBuilder::new(&uri); + let mut builder = RequestBuilder::new(uri); builder.header("Connection", "Close"); Request { @@ -888,12 +885,36 @@ impl<'a> Request<'a> { ///let response = Request::new(&uri).send(&mut writer).unwrap(); ///``` pub fn send(&self, writer: &mut T) -> Result { - let host = self.inner.uri.host().unwrap_or(""); + let mut host: String = self.inner.uri.host().unwrap_or("").to_string(); let port = self.inner.uri.corr_port(); + + let hints: WasiAddrinfo = WasiAddrinfo::default(); + let mut sockaddr = Vec::new(); + let mut sockbuff = Vec::new(); + let mut ai_canonname = Vec::new(); + let query = WasiAddrinfo::get_addrinfo( + &host, + &port.to_string(), + &hints, + 10, + &mut sockaddr, + &mut sockbuff, + &mut ai_canonname, + ) + .unwrap(); + for record in query { + if record.ai_addrlen.ne(&0) && record.ai_family.is_v4() { + host = format!( + "{}.{}.{}.{}", + sockbuff[0][2], sockbuff[0][3], sockbuff[0][4], sockbuff[0][5] + ); + break; + } + } let mut stream = TcpStream::connect((host, port))?; if self.inner.uri.scheme() == "https" { - return Err(error::Error::Tls) + Err(error::Error::Tls) } else { self.inner.send(&mut stream, writer) } @@ -1103,22 +1124,22 @@ mod tests { .unwrap(); } - #[ignore] - #[test] - fn request_b_send_secure() { - let mut writer = Vec::new(); - let uri = Uri::try_from(URI_S).unwrap(); + // #[ignore] + // #[test] + // fn request_b_send_secure() { + // let mut writer = Vec::new(); + // let uri = Uri::try_from(URI_S).unwrap(); - let stream = TcpStream::connect((uri.host().unwrap_or(""), uri.corr_port())).unwrap(); - let mut secure_stream = tls::Config::default() - .connect(uri.host().unwrap_or(""), stream) - .unwrap(); + // let stream = TcpStream::connect((uri.host().unwrap_or(""), uri.corr_port())).unwrap(); + // let mut secure_stream = tls::Config::default() + // .connect(uri.host().unwrap_or(""), stream) + // .unwrap(); - RequestBuilder::new(&Uri::try_from(URI_S).unwrap()) - .header("Connection", "Close") - .send(&mut secure_stream, &mut writer) - .unwrap(); - } + // RequestBuilder::new(&Uri::try_from(URI_S).unwrap()) + // .header("Connection", "Close") + // .send(&mut secure_stream, &mut writer) + // .unwrap(); + // } #[test] fn request_b_parse_msg() { @@ -1207,6 +1228,7 @@ mod tests { assert_eq!(request.inner.timeout, timeout); } + #[ignore] #[test] fn request_connect_timeout() { let uri = Uri::try_from(URI).unwrap(); diff --git a/src/uri.rs b/src/uri.rs index 378a602..6ce6846 100644 --- a/src/uri.rs +++ b/src/uri.rs @@ -231,11 +231,12 @@ impl<'a> Uri<'a> { pub fn resource(&self) -> &str { let mut result = "/"; - for v in &[self.path, self.query, self.fragment] { - if let Some(r) = v { - result = &self.inner[r.start..]; - break; - } + if let Some(v) = [self.path, self.query, self.fragment] + .iter() + .flatten() + .next() + { + result = &self.inner[v.start..]; } result @@ -263,14 +264,14 @@ impl<'a> TryFrom<&'a str> for Uri<'a> { type Error = Error; fn try_from(s: &'a str) -> Result { - let (scheme, mut uri_part) = get_chunks(&s, Some(RangeC::new(0, s.len())), ":"); + let (scheme, mut uri_part) = get_chunks(s, Some(RangeC::new(0, s.len())), ":"); let scheme = scheme.ok_or(ParseErr::UriErr)?; let mut authority = None; if let Some(u) = &uri_part { if s[*u].contains("//") { - let (auth, part) = get_chunks(&s, Some(RangeC::new(u.start + 2, u.end)), "/"); + let (auth, part) = get_chunks(s, Some(RangeC::new(u.start + 2, u.end)), "/"); authority = if let Some(a) = auth { Some(Authority::try_from(&s[a])?) @@ -282,13 +283,13 @@ impl<'a> TryFrom<&'a str> for Uri<'a> { } } - let (mut path, uri_part) = get_chunks(&s, uri_part, "?"); + let (mut path, uri_part) = get_chunks(s, uri_part, "?"); if authority.is_some() || &s[scheme] == "file" { path = path.map(|p| RangeC::new(p.start - 1, p.end)); } - let (query, fragment) = get_chunks(&s, uri_part, "#"); + let (query, fragment) = get_chunks(s, uri_part, "#"); Ok(Uri { inner: s, @@ -404,8 +405,8 @@ impl<'a> TryFrom<&'a str> for Authority<'a> { let mut password = None; let uri_part = if s.contains('@') { - let (info, part) = get_chunks(&s, Some(RangeC::new(0, s.len())), "@"); - let (name, pass) = get_chunks(&s, info, ":"); + let (info, part) = get_chunks(s, Some(RangeC::new(0, s.len())), "@"); + let (name, pass) = get_chunks(s, info, ":"); username = name; password = pass; @@ -420,7 +421,7 @@ impl<'a> TryFrom<&'a str> for Authority<'a> { } else { ":" }; - let (host, port) = get_chunks(&s, uri_part, split_by); + let (host, port) = get_chunks(s, uri_part, split_by); let host = host.ok_or(ParseErr::UriErr)?; if let Some(p) = port { diff --git a/tests/server.py b/tests/server.py new file mode 100644 index 0000000..801c216 --- /dev/null +++ b/tests/server.py @@ -0,0 +1,20 @@ +# Install dependencies: python3 -m pip install "uvicorn[standard]" fastapi +# Run: uvicorn server:app --port 1234 + +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + +@app.head("/get") +@app.get("/get") +def hello(): + return "Hello World" + +class Item(BaseModel): + field1: str + field2: str + +@app.post("/post") +def read_item(item: Item): + return item \ No newline at end of file