Skip to main content

Gpus

Struct Gpus 

Source
pub struct Gpus { /* private fields */ }
Expand description

Type containing GPU information.

It is returned by Gpus.

It is currently supported on Linux and macOS.

use sysinfo::Gpus;

if let Ok(gpus) = Gpus::new_with_refreshed_list() {
    for gpu in &gpus {
        println!("{gpu:?}");
    }
}

Implementations§

Source§

impl Gpus

Source

pub fn new() -> Result<Self, Error>

Creates a new empty Gpus type.

If you want it to be filled directly, take a look at Gpus::new_with_refreshed_list.

use sysinfo::Gpus;

if let Ok(mut gpus) = Gpus::new() {
    gpus.refresh(true);
    for gpu in &gpus {
        println!("{gpu:?}");
    }
}
Examples found in repository?
examples/simple.rs (line 514)
507fn main() {
508    println!("Getting system information...");
509    let mut system = System::new_all();
510    let mut networks = Networks::new_with_refreshed_list();
511    let mut disks = Disks::new_with_refreshed_list();
512    let mut components = Components::new_with_refreshed_list();
513    let mut users = Users::new_with_refreshed_list();
514    let mut gpus = Gpus::new();
515
516    println!("Done.");
517    let t_stin = io::stdin();
518    let mut stin = t_stin.lock();
519    let mut done = false;
520
521    println!("To get the commands' list, enter 'help'.");
522    while !done {
523        let mut input = String::new();
524        write!(&mut io::stdout(), "> ");
525        io::stdout().flush();
526
527        stin.read_line(&mut input);
528        if input.is_empty() {
529            // The string is empty, meaning there is no '\n', meaning
530            // that the user used CTRL+D so we can just quit!
531            println!("\nLeaving, bye!");
532            break;
533        }
534        if (&input as &str).ends_with('\n') {
535            input.pop();
536        }
537        done = interpret_input(
538            input.as_ref(),
539            system.as_mut(),
540            gpus.as_mut(),
541            networks.as_mut(),
542            disks.as_mut(),
543            components.as_mut(),
544            users.as_mut(),
545        );
546    }
547}
Source

pub fn new_with_refreshed_list() -> Result<Self, Error>

Creates a new Gpus type with the GPU list loaded.

use sysinfo::Gpus;

if let Ok(gpus) = Gpus::new_with_refreshed_list() {
    for gpu in &gpus {
        println!("{gpu:?}");
    }
}
Source

pub fn refresh(&mut self, remove_not_listed_gpus: bool)

Refreshes the list of GPUs.

use sysinfo::Gpus;

if let Ok(mut gpus) = Gpus::new_with_refreshed_list() {
    // Wait some time...? Then refresh the data of each GPU.
    gpus.refresh(true);
}
Examples found in repository?
examples/simple.rs (line 163)
74fn interpret_input(
75    input: &str,
76    sys: Result<&mut System, &mut Error>,
77    gpus: Result<&mut Gpus, &mut Error>,
78    networks: Result<&mut Networks, &mut Error>,
79    disks: Result<&mut Disks, &mut Error>,
80    components: Result<&mut Components, &mut Error>,
81    users: Result<&mut Users, &mut Error>,
82) -> bool {
83    match input.trim() {
84        "help" => print_help(),
85        "refresh_disks" => match disks {
86            Ok(disks) => {
87                println!("Refreshing disk list...");
88                disks.refresh(true);
89                println!("Done.");
90            }
91            Err(error) => {
92                println!("Disks information cannot be retrieved: {error}");
93            }
94        },
95        "refresh_users" => match users {
96            Ok(users) => {
97                println!("Refreshing user list...");
98                users.refresh();
99                println!("Done.");
100            }
101            Err(error) => {
102                println!("Users information cannot be retrieved: {error}");
103            }
104        },
105        "refresh_networks" => match networks {
106            Ok(networks) => {
107                println!("Refreshing network list...");
108                networks.refresh(true);
109                println!("Done.");
110            }
111            Err(error) => {
112                println!("Networks information cannot be retrieved: {error}");
113            }
114        },
115        "refresh_components" => match components {
116            Ok(components) => {
117                println!("Refreshing component list...");
118                components.refresh(true);
119                println!("Done.");
120            }
121            Err(error) => {
122                println!("Components information cannot be retrieved: {error}");
123            }
124        },
125        "refresh_cpu" => match sys {
126            Ok(sys) => {
127                println!("Refreshing CPUs...");
128                sys.refresh_cpu_all();
129                println!("Done.");
130            }
131            Err(error) => {
132                println!("System information cannot be retrieved: {error}");
133            }
134        },
135        "signals" => {
136            for (nb, sig) in SUPPORTED_SIGNALS.iter().enumerate() {
137                println!("{:2}:{sig:?}", nb + 1);
138            }
139        }
140        "cpus" => {
141            match sys {
142                Ok(sys) => {
143                    // Note: you should refresh a few times before using this, so that usage statistics
144                    // can be ascertained
145                    println!(
146                        "number of physical cores: {}",
147                        System::physical_core_count()
148                            .map(|c| c.to_string())
149                            .unwrap_or_else(|_| "Unknown".to_owned()),
150                    );
151                    println!("total CPU usage: {}%", sys.global_cpu_usage());
152                    for cpu in sys.cpus() {
153                        println!("{cpu:?}");
154                    }
155                }
156                Err(error) => {
157                    println!("System information cannot be retrieved: {error}");
158                }
159            }
160        }
161        "gpus" => match gpus {
162            Ok(gpus) => {
163                gpus.refresh(true);
164                for gpu in &*gpus {
165                    println!(
166                        "GPU (PCI: {}): Vendor: {}",
167                        gpu.pci(),
168                        gpu.vendor().unwrap_or("Unknown")
169                    );
170                    if let Some(model) = gpu.model() {
171                        println!("  model: {model}");
172                    }
173                    match gpu.usage() {
174                        Some(usage) => println!("  usage: {usage}%"),
175                        None => println!("  usage: N/A"),
176                    }
177                    if let (Some(used), Some(total)) = (gpu.used_memory(), gpu.total_memory()) {
178                        println!("  memory: {}/{} KB", used / 1_000, total / 1_000);
179                    } else {
180                        println!("  memory: N/A");
181                    }
182                }
183            }
184            Err(error) => {
185                println!("GPU information cannot be retrieved on this system: {error}");
186            }
187        },
188        "memory" => match sys {
189            Ok(sys) => {
190                println!("total memory:     {: >10} KB", sys.total_memory() / 1_000);
191                println!(
192                    "available memory: {: >10} KB",
193                    sys.available_memory() / 1_000
194                );
195                println!("used memory:      {: >10} KB", sys.used_memory() / 1_000);
196                println!("total swap:       {: >10} KB", sys.total_swap() / 1_000);
197                println!("used swap:        {: >10} KB", sys.used_swap() / 1_000);
198            }
199            Err(error) => {
200                println!("System information cannot be retrieved: {error}");
201            }
202        },
203        "quit" | "exit" => return true,
204        "all" => match sys {
205            Ok(sys) => {
206                for (pid, proc_) in sys.processes() {
207                    println!(
208                        "{}:{} status={:?}",
209                        pid,
210                        proc_.name().to_string_lossy(),
211                        proc_.status()
212                    );
213                }
214            }
215            Err(error) => {
216                println!("System information cannot be retrieved: {error}");
217            }
218        },
219        "frequency" => match sys {
220            Ok(sys) => {
221                for cpu in sys.cpus() {
222                    println!("[{}] {} MHz", cpu.name(), cpu.frequency());
223                }
224            }
225            Err(error) => {
226                println!("System information cannot be retrieved: {error}");
227            }
228        },
229        "vendor_id" => match sys {
230            Ok(sys) => {
231                println!("vendor ID: {}", sys.cpus()[0].vendor_id());
232            }
233            Err(error) => {
234                println!("System information cannot be retrieved: {error}");
235            }
236        },
237        "brand" => match sys {
238            Ok(sys) => {
239                println!("brand: {}", sys.cpus()[0].brand());
240            }
241            Err(error) => {
242                println!("System information cannot be retrieved: {error}");
243            }
244        },
245        "load_avg" => match System::load_average() {
246            Ok(load_avg) => {
247                println!("one minute     : {}%", load_avg.one);
248                println!("five minutes   : {}%", load_avg.five);
249                println!("fifteen minutes: {}%", load_avg.fifteen);
250            }
251            Err(error) => {
252                eprintln!("Failed to get `load_average`: {error}");
253            }
254        },
255        e if e.starts_with("show ") => {
256            let tmp: Vec<&str> = e.split(' ').filter(|s| !s.is_empty()).collect();
257
258            if tmp.len() != 2 {
259                println!("show command takes a pid or a name in parameter!");
260                println!("example: show 1254");
261            } else {
262                match sys {
263                    Ok(sys) => {
264                        if let Ok(pid) = Pid::from_str(tmp[1]) {
265                            match sys.process(pid) {
266                                Some(p) => {
267                                    println!("{:#?}", *p);
268                                    println!(
269                                        "Files open/limit: {:?}/{:?}",
270                                        p.open_files(),
271                                        p.open_files_limit(),
272                                    );
273                                }
274                                None => {
275                                    println!("pid \"{pid:?}\" not found");
276                                }
277                            }
278                        } else {
279                            let proc_name = tmp[1];
280                            for proc_ in sys.processes_by_name(proc_name.as_ref()) {
281                                println!("==== {} ====", proc_.name().to_string_lossy());
282                                println!("{proc_:?}");
283                            }
284                        }
285                    }
286                    Err(error) => {
287                        println!("System information cannot be retrieved: {error}");
288                    }
289                }
290            }
291        }
292        "temperature" => match components {
293            Ok(components) => {
294                for component in components.iter() {
295                    println!("{component:?}");
296                }
297            }
298            Err(error) => {
299                println!("Components information cannot be retrieved: {error}");
300            }
301        },
302        "network" => match networks {
303            Ok(networks) => {
304                for (interface_name, data) in networks.iter() {
305                    println!(
306                        "\
307    {}:
308      operational state {}
309      ether {}
310      input data  (new / total): {} / {} B
311      output data (new / total): {} / {} B",
312                        interface_name.display(),
313                        data.operational_state(),
314                        data.mac_address(),
315                        data.received(),
316                        data.total_received(),
317                        data.transmitted(),
318                        data.total_transmitted(),
319                    );
320                }
321            }
322            Err(error) => {
323                println!("Networks information cannot be retrieved: {error}");
324            }
325        },
326        "show" => {
327            println!("'show' command expects a pid number or a process name");
328        }
329        e if e.starts_with("kill ") => {
330            let tmp: Vec<&str> = e
331                .split(' ')
332                .map(|s| s.trim())
333                .filter(|s| !s.is_empty())
334                .collect();
335
336            if tmp.len() != 3 {
337                println!("kill command takes the pid and a signal number in parameter!");
338                println!("example: kill 1254 9");
339            } else {
340                let Ok(pid) = Pid::from_str(tmp[1]) else {
341                    eprintln!("Expected a number for the PID, found {:?}", tmp[1]);
342                    return false;
343                };
344                let Ok(signal) = usize::from_str(tmp[2]) else {
345                    eprintln!("Expected a number for the signal, found {:?}", tmp[2]);
346                    return false;
347                };
348                let Some(signal) = SUPPORTED_SIGNALS.get(signal) else {
349                    eprintln!(
350                        "No signal matching {signal}. Use the `signals` command to get the \
351                         list of signals.",
352                    );
353                    return false;
354                };
355
356                match sys {
357                    Ok(sys) => match sys.process(pid) {
358                        Some(p) => {
359                            if let Some(res) = p.kill_with(*signal) {
360                                println!("kill: {res}");
361                            } else {
362                                eprintln!("kill: signal not supported on this platform");
363                            }
364                        }
365                        None => {
366                            eprintln!("pid not found");
367                        }
368                    },
369                    Err(error) => {
370                        println!("System information cannot be retrieved: {error}");
371                    }
372                }
373            }
374        }
375        "disks" => match disks {
376            Ok(disks) => {
377                for disk in disks {
378                    println!("{disk:?}");
379                }
380            }
381            Err(error) => {
382                println!("Disks information cannot be retrieved: {error}");
383            }
384        },
385        "users" => match users {
386            Ok(users) => {
387                for user in users {
388                    println!("{:?} => {:?}", user.name(), user.groups());
389                }
390            }
391            Err(error) => {
392                println!("Users information cannot be retrieved: {error}");
393            }
394        },
395        "groups" => match Groups::new_with_refreshed_list() {
396            Ok(groups) => {
397                for group in &groups {
398                    println!("{group:?}");
399                }
400            }
401            Err(error) => {
402                println!("Groups information cannot be retrieved: {error}");
403            }
404        },
405        "boot_time" => match System::boot_time() {
406            Ok(boot_time) => println!("{boot_time} seconds"),
407            Err(error) => eprintln!("Failed to get `boot_time`: {error}"),
408        },
409        "uptime" => match System::uptime() {
410            Ok(up) => {
411                let mut uptime = up;
412                let days = uptime / 86400;
413                uptime -= days * 86400;
414                let hours = uptime / 3600;
415                uptime -= hours * 3600;
416                let minutes = uptime / 60;
417                println!("{days} days {hours} hours {minutes} minutes ({up} seconds in total)");
418            }
419            Err(error) => eprintln!("Failed to get `uptime`: {error}"),
420        },
421        x if x.starts_with("refresh") => {
422            if x == "refresh" {
423                match sys {
424                    Ok(sys) => {
425                        println!("Getting processes' information...");
426                        sys.refresh_all();
427                        println!("Done.");
428                    }
429                    Err(error) => {
430                        println!("System information cannot be retrieved: {error}");
431                    }
432                }
433            } else if x.starts_with("refresh ") {
434                println!("Getting process' information...");
435                if let Some(pid) = x
436                    .split(' ')
437                    .filter_map(|pid| pid.parse().ok())
438                    .take(1)
439                    .next()
440                {
441                    match sys {
442                        Ok(sys) => {
443                            if sys.refresh_processes_specifics(
444                                sysinfo::ProcessesToUpdate::Some(&[pid]),
445                                true,
446                                ProcessRefreshKind::everything(),
447                            ) != 0
448                            {
449                                println!("Process `{pid}` updated successfully");
450                            } else {
451                                println!("Process `{pid}` couldn't be updated...");
452                            }
453                        }
454                        Err(error) => {
455                            println!("System information cannot be retrieved: {error}");
456                        }
457                    }
458                } else {
459                    println!("Invalid [pid] received...");
460                }
461            } else {
462                println!(
463                    "\"{x}\": Unknown command. Enter 'help' if you want to get the commands' \
464                     list.",
465                );
466            }
467        }
468        "pid" => {
469            println!(
470                "PID: {}",
471                sysinfo::get_current_pid().expect("failed to get PID")
472            );
473        }
474        "system" => {
475            println!(
476                "System name:              {}\n\
477                 System kernel version:    {}\n\
478                 System OS version:        {}\n\
479                 System OS (long) version: {}\n\
480                 System host name:         {}\n\
481                 System kernel:            {}",
482                System::name().unwrap_or_else(|_| "<unknown>".to_owned()),
483                System::kernel_version().unwrap_or_else(|_| "<unknown>".to_owned()),
484                System::os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
485                System::long_os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
486                System::host_name().unwrap_or_else(|_| "<unknown>".to_owned()),
487                System::kernel_long_version().unwrap_or_else(|_| "<unknown>".to_owned()),
488            );
489        }
490        "motherboard" => match Motherboard::new() {
491            Ok(m) => println!("{m:#?}"),
492            Err(error) => println!("Cannot retrieve motherboard information: {error:?}"),
493        },
494        "product" => {
495            println!("{:#?}", Product);
496        }
497        e => {
498            println!(
499                "\"{e}\": Unknown command. Enter 'help' if you want to get the commands' \
500                 list.",
501            );
502        }
503    }
504    false
505}

Methods from Deref<Target = [Gpu]>§

1.0.0

pub fn len(&self) -> usize

Returns the number of elements in the slice.

§Examples
let a = [1, 2, 3];
assert_eq!(a.len(), 3);
1.0.0

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

§Examples
let a = [1, 2, 3];
assert!(!a.is_empty());

let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());

let w: &[i32] = &[];
assert_eq!(None, w.first());
1.5.0

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first() {
    assert_eq!(first, &0);
    assert_eq!(elements, &[1, 2]);
}
1.5.0

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last() {
    assert_eq!(last, &2);
    assert_eq!(elements, &[0, 1]);
}
1.0.0

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());

let w: &[i32] = &[];
assert_eq!(None, w.last());
1.77.0

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Returns an array reference to the first N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.first_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.first_chunk::<0>());
1.77.0

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Returns an array reference to the first N items in the slice and the remaining slice.

If the slice is not at least N in length, this will return None.

§Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first_chunk::<2>() {
    assert_eq!(first, &[0, 1]);
    assert_eq!(elements, &[2]);
}

assert_eq!(None, x.split_first_chunk::<4>());
1.77.0

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Returns an array reference to the last N items in the slice and the remaining slice.

If the slice is not at least N in length, this will return None.

§Examples
let x = &[0, 1, 2];

if let Some((elements, last)) = x.split_last_chunk::<2>() {
    assert_eq!(elements, &[0]);
    assert_eq!(last, &[1, 2]);
}

assert_eq!(None, x.split_last_chunk::<4>());
1.77.0

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Returns an array reference to the last N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.last_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.last_chunk::<0>());
1.0.0

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of index.

  • If given a position, returns a reference to the element at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
Examples found in repository?
examples/simple.rs (line 348)
74fn interpret_input(
75    input: &str,
76    sys: Result<&mut System, &mut Error>,
77    gpus: Result<&mut Gpus, &mut Error>,
78    networks: Result<&mut Networks, &mut Error>,
79    disks: Result<&mut Disks, &mut Error>,
80    components: Result<&mut Components, &mut Error>,
81    users: Result<&mut Users, &mut Error>,
82) -> bool {
83    match input.trim() {
84        "help" => print_help(),
85        "refresh_disks" => match disks {
86            Ok(disks) => {
87                println!("Refreshing disk list...");
88                disks.refresh(true);
89                println!("Done.");
90            }
91            Err(error) => {
92                println!("Disks information cannot be retrieved: {error}");
93            }
94        },
95        "refresh_users" => match users {
96            Ok(users) => {
97                println!("Refreshing user list...");
98                users.refresh();
99                println!("Done.");
100            }
101            Err(error) => {
102                println!("Users information cannot be retrieved: {error}");
103            }
104        },
105        "refresh_networks" => match networks {
106            Ok(networks) => {
107                println!("Refreshing network list...");
108                networks.refresh(true);
109                println!("Done.");
110            }
111            Err(error) => {
112                println!("Networks information cannot be retrieved: {error}");
113            }
114        },
115        "refresh_components" => match components {
116            Ok(components) => {
117                println!("Refreshing component list...");
118                components.refresh(true);
119                println!("Done.");
120            }
121            Err(error) => {
122                println!("Components information cannot be retrieved: {error}");
123            }
124        },
125        "refresh_cpu" => match sys {
126            Ok(sys) => {
127                println!("Refreshing CPUs...");
128                sys.refresh_cpu_all();
129                println!("Done.");
130            }
131            Err(error) => {
132                println!("System information cannot be retrieved: {error}");
133            }
134        },
135        "signals" => {
136            for (nb, sig) in SUPPORTED_SIGNALS.iter().enumerate() {
137                println!("{:2}:{sig:?}", nb + 1);
138            }
139        }
140        "cpus" => {
141            match sys {
142                Ok(sys) => {
143                    // Note: you should refresh a few times before using this, so that usage statistics
144                    // can be ascertained
145                    println!(
146                        "number of physical cores: {}",
147                        System::physical_core_count()
148                            .map(|c| c.to_string())
149                            .unwrap_or_else(|_| "Unknown".to_owned()),
150                    );
151                    println!("total CPU usage: {}%", sys.global_cpu_usage());
152                    for cpu in sys.cpus() {
153                        println!("{cpu:?}");
154                    }
155                }
156                Err(error) => {
157                    println!("System information cannot be retrieved: {error}");
158                }
159            }
160        }
161        "gpus" => match gpus {
162            Ok(gpus) => {
163                gpus.refresh(true);
164                for gpu in &*gpus {
165                    println!(
166                        "GPU (PCI: {}): Vendor: {}",
167                        gpu.pci(),
168                        gpu.vendor().unwrap_or("Unknown")
169                    );
170                    if let Some(model) = gpu.model() {
171                        println!("  model: {model}");
172                    }
173                    match gpu.usage() {
174                        Some(usage) => println!("  usage: {usage}%"),
175                        None => println!("  usage: N/A"),
176                    }
177                    if let (Some(used), Some(total)) = (gpu.used_memory(), gpu.total_memory()) {
178                        println!("  memory: {}/{} KB", used / 1_000, total / 1_000);
179                    } else {
180                        println!("  memory: N/A");
181                    }
182                }
183            }
184            Err(error) => {
185                println!("GPU information cannot be retrieved on this system: {error}");
186            }
187        },
188        "memory" => match sys {
189            Ok(sys) => {
190                println!("total memory:     {: >10} KB", sys.total_memory() / 1_000);
191                println!(
192                    "available memory: {: >10} KB",
193                    sys.available_memory() / 1_000
194                );
195                println!("used memory:      {: >10} KB", sys.used_memory() / 1_000);
196                println!("total swap:       {: >10} KB", sys.total_swap() / 1_000);
197                println!("used swap:        {: >10} KB", sys.used_swap() / 1_000);
198            }
199            Err(error) => {
200                println!("System information cannot be retrieved: {error}");
201            }
202        },
203        "quit" | "exit" => return true,
204        "all" => match sys {
205            Ok(sys) => {
206                for (pid, proc_) in sys.processes() {
207                    println!(
208                        "{}:{} status={:?}",
209                        pid,
210                        proc_.name().to_string_lossy(),
211                        proc_.status()
212                    );
213                }
214            }
215            Err(error) => {
216                println!("System information cannot be retrieved: {error}");
217            }
218        },
219        "frequency" => match sys {
220            Ok(sys) => {
221                for cpu in sys.cpus() {
222                    println!("[{}] {} MHz", cpu.name(), cpu.frequency());
223                }
224            }
225            Err(error) => {
226                println!("System information cannot be retrieved: {error}");
227            }
228        },
229        "vendor_id" => match sys {
230            Ok(sys) => {
231                println!("vendor ID: {}", sys.cpus()[0].vendor_id());
232            }
233            Err(error) => {
234                println!("System information cannot be retrieved: {error}");
235            }
236        },
237        "brand" => match sys {
238            Ok(sys) => {
239                println!("brand: {}", sys.cpus()[0].brand());
240            }
241            Err(error) => {
242                println!("System information cannot be retrieved: {error}");
243            }
244        },
245        "load_avg" => match System::load_average() {
246            Ok(load_avg) => {
247                println!("one minute     : {}%", load_avg.one);
248                println!("five minutes   : {}%", load_avg.five);
249                println!("fifteen minutes: {}%", load_avg.fifteen);
250            }
251            Err(error) => {
252                eprintln!("Failed to get `load_average`: {error}");
253            }
254        },
255        e if e.starts_with("show ") => {
256            let tmp: Vec<&str> = e.split(' ').filter(|s| !s.is_empty()).collect();
257
258            if tmp.len() != 2 {
259                println!("show command takes a pid or a name in parameter!");
260                println!("example: show 1254");
261            } else {
262                match sys {
263                    Ok(sys) => {
264                        if let Ok(pid) = Pid::from_str(tmp[1]) {
265                            match sys.process(pid) {
266                                Some(p) => {
267                                    println!("{:#?}", *p);
268                                    println!(
269                                        "Files open/limit: {:?}/{:?}",
270                                        p.open_files(),
271                                        p.open_files_limit(),
272                                    );
273                                }
274                                None => {
275                                    println!("pid \"{pid:?}\" not found");
276                                }
277                            }
278                        } else {
279                            let proc_name = tmp[1];
280                            for proc_ in sys.processes_by_name(proc_name.as_ref()) {
281                                println!("==== {} ====", proc_.name().to_string_lossy());
282                                println!("{proc_:?}");
283                            }
284                        }
285                    }
286                    Err(error) => {
287                        println!("System information cannot be retrieved: {error}");
288                    }
289                }
290            }
291        }
292        "temperature" => match components {
293            Ok(components) => {
294                for component in components.iter() {
295                    println!("{component:?}");
296                }
297            }
298            Err(error) => {
299                println!("Components information cannot be retrieved: {error}");
300            }
301        },
302        "network" => match networks {
303            Ok(networks) => {
304                for (interface_name, data) in networks.iter() {
305                    println!(
306                        "\
307    {}:
308      operational state {}
309      ether {}
310      input data  (new / total): {} / {} B
311      output data (new / total): {} / {} B",
312                        interface_name.display(),
313                        data.operational_state(),
314                        data.mac_address(),
315                        data.received(),
316                        data.total_received(),
317                        data.transmitted(),
318                        data.total_transmitted(),
319                    );
320                }
321            }
322            Err(error) => {
323                println!("Networks information cannot be retrieved: {error}");
324            }
325        },
326        "show" => {
327            println!("'show' command expects a pid number or a process name");
328        }
329        e if e.starts_with("kill ") => {
330            let tmp: Vec<&str> = e
331                .split(' ')
332                .map(|s| s.trim())
333                .filter(|s| !s.is_empty())
334                .collect();
335
336            if tmp.len() != 3 {
337                println!("kill command takes the pid and a signal number in parameter!");
338                println!("example: kill 1254 9");
339            } else {
340                let Ok(pid) = Pid::from_str(tmp[1]) else {
341                    eprintln!("Expected a number for the PID, found {:?}", tmp[1]);
342                    return false;
343                };
344                let Ok(signal) = usize::from_str(tmp[2]) else {
345                    eprintln!("Expected a number for the signal, found {:?}", tmp[2]);
346                    return false;
347                };
348                let Some(signal) = SUPPORTED_SIGNALS.get(signal) else {
349                    eprintln!(
350                        "No signal matching {signal}. Use the `signals` command to get the \
351                         list of signals.",
352                    );
353                    return false;
354                };
355
356                match sys {
357                    Ok(sys) => match sys.process(pid) {
358                        Some(p) => {
359                            if let Some(res) = p.kill_with(*signal) {
360                                println!("kill: {res}");
361                            } else {
362                                eprintln!("kill: signal not supported on this platform");
363                            }
364                        }
365                        None => {
366                            eprintln!("pid not found");
367                        }
368                    },
369                    Err(error) => {
370                        println!("System information cannot be retrieved: {error}");
371                    }
372                }
373            }
374        }
375        "disks" => match disks {
376            Ok(disks) => {
377                for disk in disks {
378                    println!("{disk:?}");
379                }
380            }
381            Err(error) => {
382                println!("Disks information cannot be retrieved: {error}");
383            }
384        },
385        "users" => match users {
386            Ok(users) => {
387                for user in users {
388                    println!("{:?} => {:?}", user.name(), user.groups());
389                }
390            }
391            Err(error) => {
392                println!("Users information cannot be retrieved: {error}");
393            }
394        },
395        "groups" => match Groups::new_with_refreshed_list() {
396            Ok(groups) => {
397                for group in &groups {
398                    println!("{group:?}");
399                }
400            }
401            Err(error) => {
402                println!("Groups information cannot be retrieved: {error}");
403            }
404        },
405        "boot_time" => match System::boot_time() {
406            Ok(boot_time) => println!("{boot_time} seconds"),
407            Err(error) => eprintln!("Failed to get `boot_time`: {error}"),
408        },
409        "uptime" => match System::uptime() {
410            Ok(up) => {
411                let mut uptime = up;
412                let days = uptime / 86400;
413                uptime -= days * 86400;
414                let hours = uptime / 3600;
415                uptime -= hours * 3600;
416                let minutes = uptime / 60;
417                println!("{days} days {hours} hours {minutes} minutes ({up} seconds in total)");
418            }
419            Err(error) => eprintln!("Failed to get `uptime`: {error}"),
420        },
421        x if x.starts_with("refresh") => {
422            if x == "refresh" {
423                match sys {
424                    Ok(sys) => {
425                        println!("Getting processes' information...");
426                        sys.refresh_all();
427                        println!("Done.");
428                    }
429                    Err(error) => {
430                        println!("System information cannot be retrieved: {error}");
431                    }
432                }
433            } else if x.starts_with("refresh ") {
434                println!("Getting process' information...");
435                if let Some(pid) = x
436                    .split(' ')
437                    .filter_map(|pid| pid.parse().ok())
438                    .take(1)
439                    .next()
440                {
441                    match sys {
442                        Ok(sys) => {
443                            if sys.refresh_processes_specifics(
444                                sysinfo::ProcessesToUpdate::Some(&[pid]),
445                                true,
446                                ProcessRefreshKind::everything(),
447                            ) != 0
448                            {
449                                println!("Process `{pid}` updated successfully");
450                            } else {
451                                println!("Process `{pid}` couldn't be updated...");
452                            }
453                        }
454                        Err(error) => {
455                            println!("System information cannot be retrieved: {error}");
456                        }
457                    }
458                } else {
459                    println!("Invalid [pid] received...");
460                }
461            } else {
462                println!(
463                    "\"{x}\": Unknown command. Enter 'help' if you want to get the commands' \
464                     list.",
465                );
466            }
467        }
468        "pid" => {
469            println!(
470                "PID: {}",
471                sysinfo::get_current_pid().expect("failed to get PID")
472            );
473        }
474        "system" => {
475            println!(
476                "System name:              {}\n\
477                 System kernel version:    {}\n\
478                 System OS version:        {}\n\
479                 System OS (long) version: {}\n\
480                 System host name:         {}\n\
481                 System kernel:            {}",
482                System::name().unwrap_or_else(|_| "<unknown>".to_owned()),
483                System::kernel_version().unwrap_or_else(|_| "<unknown>".to_owned()),
484                System::os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
485                System::long_os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
486                System::host_name().unwrap_or_else(|_| "<unknown>".to_owned()),
487                System::kernel_long_version().unwrap_or_else(|_| "<unknown>".to_owned()),
488            );
489        }
490        "motherboard" => match Motherboard::new() {
491            Ok(m) => println!("{m:#?}"),
492            Err(error) => println!("Cannot retrieve motherboard information: {error:?}"),
493        },
494        "product" => {
495            println!("{:#?}", Product);
496        }
497        e => {
498            println!(
499                "\"{e}\": Unknown command. Enter 'help' if you want to get the commands' \
500                 list.",
501            );
502        }
503    }
504    false
505}
1.0.0

pub unsafe fn get_unchecked<I>( &self, index: I, ) -> &<I as SliceIndex<[T]>>::Output
where I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds checking.

For a safe alternative see get.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

You can think of this like .get(index).unwrap_unchecked(). It’s UB to call .get_unchecked(len), even if you immediately convert to a pointer. And it’s UB to call .get_unchecked(..len + 1), .get_unchecked(..=len), or similar.

§Examples
let x = &[1, 2, 4];

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}
1.0.0

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

The caller must ensure that the slice outlives the pointer this function returns, or else it will end up dangling.

The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

§Examples
let x = &[1, 2, 4];
let x_ptr = x.as_ptr();

unsafe {
    for i in 0..x.len() {
        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
    }
}
1.48.0

pub fn as_ptr_range(&self) -> Range<*const T> ⓘ

Returns the two raw pointers spanning the slice.

The returned range is half-open, which means that the end pointer points one past the last element of the slice. This way, an empty slice is represented by two equal pointers, and the difference between the two pointers represents the size of the slice.

See as_ptr for warnings on using these pointers. The end pointer requires extra caution, as it does not point to a valid element in the slice.

This function is useful for interacting with foreign interfaces which use two pointers to refer to a range of elements in memory, as is common in C++.

It can also be useful to check if a pointer to an element refers to an element of this slice:

let a = [1, 2, 3];
let x = &a[1] as *const _;
let y = &5 as *const _;

assert!(a.as_ptr_range().contains(&x));
assert!(!a.as_ptr_range().contains(&y));
1.93.0

pub fn as_array<const N: usize>(&self) -> Option<&[T; N]>

Gets a reference to the underlying array.

If N is not exactly equal to the length of self, then this method returns None.

1.0.0

pub fn iter(&self) -> Iter<'_, T> ⓘ

Returns an iterator over the slice.

The iterator yields all items from start to end.

§Examples
let x = &[1, 2, 4];
let mut iterator = x.iter();

assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
Examples found in repository?
examples/simple.rs (line 136)
74fn interpret_input(
75    input: &str,
76    sys: Result<&mut System, &mut Error>,
77    gpus: Result<&mut Gpus, &mut Error>,
78    networks: Result<&mut Networks, &mut Error>,
79    disks: Result<&mut Disks, &mut Error>,
80    components: Result<&mut Components, &mut Error>,
81    users: Result<&mut Users, &mut Error>,
82) -> bool {
83    match input.trim() {
84        "help" => print_help(),
85        "refresh_disks" => match disks {
86            Ok(disks) => {
87                println!("Refreshing disk list...");
88                disks.refresh(true);
89                println!("Done.");
90            }
91            Err(error) => {
92                println!("Disks information cannot be retrieved: {error}");
93            }
94        },
95        "refresh_users" => match users {
96            Ok(users) => {
97                println!("Refreshing user list...");
98                users.refresh();
99                println!("Done.");
100            }
101            Err(error) => {
102                println!("Users information cannot be retrieved: {error}");
103            }
104        },
105        "refresh_networks" => match networks {
106            Ok(networks) => {
107                println!("Refreshing network list...");
108                networks.refresh(true);
109                println!("Done.");
110            }
111            Err(error) => {
112                println!("Networks information cannot be retrieved: {error}");
113            }
114        },
115        "refresh_components" => match components {
116            Ok(components) => {
117                println!("Refreshing component list...");
118                components.refresh(true);
119                println!("Done.");
120            }
121            Err(error) => {
122                println!("Components information cannot be retrieved: {error}");
123            }
124        },
125        "refresh_cpu" => match sys {
126            Ok(sys) => {
127                println!("Refreshing CPUs...");
128                sys.refresh_cpu_all();
129                println!("Done.");
130            }
131            Err(error) => {
132                println!("System information cannot be retrieved: {error}");
133            }
134        },
135        "signals" => {
136            for (nb, sig) in SUPPORTED_SIGNALS.iter().enumerate() {
137                println!("{:2}:{sig:?}", nb + 1);
138            }
139        }
140        "cpus" => {
141            match sys {
142                Ok(sys) => {
143                    // Note: you should refresh a few times before using this, so that usage statistics
144                    // can be ascertained
145                    println!(
146                        "number of physical cores: {}",
147                        System::physical_core_count()
148                            .map(|c| c.to_string())
149                            .unwrap_or_else(|_| "Unknown".to_owned()),
150                    );
151                    println!("total CPU usage: {}%", sys.global_cpu_usage());
152                    for cpu in sys.cpus() {
153                        println!("{cpu:?}");
154                    }
155                }
156                Err(error) => {
157                    println!("System information cannot be retrieved: {error}");
158                }
159            }
160        }
161        "gpus" => match gpus {
162            Ok(gpus) => {
163                gpus.refresh(true);
164                for gpu in &*gpus {
165                    println!(
166                        "GPU (PCI: {}): Vendor: {}",
167                        gpu.pci(),
168                        gpu.vendor().unwrap_or("Unknown")
169                    );
170                    if let Some(model) = gpu.model() {
171                        println!("  model: {model}");
172                    }
173                    match gpu.usage() {
174                        Some(usage) => println!("  usage: {usage}%"),
175                        None => println!("  usage: N/A"),
176                    }
177                    if let (Some(used), Some(total)) = (gpu.used_memory(), gpu.total_memory()) {
178                        println!("  memory: {}/{} KB", used / 1_000, total / 1_000);
179                    } else {
180                        println!("  memory: N/A");
181                    }
182                }
183            }
184            Err(error) => {
185                println!("GPU information cannot be retrieved on this system: {error}");
186            }
187        },
188        "memory" => match sys {
189            Ok(sys) => {
190                println!("total memory:     {: >10} KB", sys.total_memory() / 1_000);
191                println!(
192                    "available memory: {: >10} KB",
193                    sys.available_memory() / 1_000
194                );
195                println!("used memory:      {: >10} KB", sys.used_memory() / 1_000);
196                println!("total swap:       {: >10} KB", sys.total_swap() / 1_000);
197                println!("used swap:        {: >10} KB", sys.used_swap() / 1_000);
198            }
199            Err(error) => {
200                println!("System information cannot be retrieved: {error}");
201            }
202        },
203        "quit" | "exit" => return true,
204        "all" => match sys {
205            Ok(sys) => {
206                for (pid, proc_) in sys.processes() {
207                    println!(
208                        "{}:{} status={:?}",
209                        pid,
210                        proc_.name().to_string_lossy(),
211                        proc_.status()
212                    );
213                }
214            }
215            Err(error) => {
216                println!("System information cannot be retrieved: {error}");
217            }
218        },
219        "frequency" => match sys {
220            Ok(sys) => {
221                for cpu in sys.cpus() {
222                    println!("[{}] {} MHz", cpu.name(), cpu.frequency());
223                }
224            }
225            Err(error) => {
226                println!("System information cannot be retrieved: {error}");
227            }
228        },
229        "vendor_id" => match sys {
230            Ok(sys) => {
231                println!("vendor ID: {}", sys.cpus()[0].vendor_id());
232            }
233            Err(error) => {
234                println!("System information cannot be retrieved: {error}");
235            }
236        },
237        "brand" => match sys {
238            Ok(sys) => {
239                println!("brand: {}", sys.cpus()[0].brand());
240            }
241            Err(error) => {
242                println!("System information cannot be retrieved: {error}");
243            }
244        },
245        "load_avg" => match System::load_average() {
246            Ok(load_avg) => {
247                println!("one minute     : {}%", load_avg.one);
248                println!("five minutes   : {}%", load_avg.five);
249                println!("fifteen minutes: {}%", load_avg.fifteen);
250            }
251            Err(error) => {
252                eprintln!("Failed to get `load_average`: {error}");
253            }
254        },
255        e if e.starts_with("show ") => {
256            let tmp: Vec<&str> = e.split(' ').filter(|s| !s.is_empty()).collect();
257
258            if tmp.len() != 2 {
259                println!("show command takes a pid or a name in parameter!");
260                println!("example: show 1254");
261            } else {
262                match sys {
263                    Ok(sys) => {
264                        if let Ok(pid) = Pid::from_str(tmp[1]) {
265                            match sys.process(pid) {
266                                Some(p) => {
267                                    println!("{:#?}", *p);
268                                    println!(
269                                        "Files open/limit: {:?}/{:?}",
270                                        p.open_files(),
271                                        p.open_files_limit(),
272                                    );
273                                }
274                                None => {
275                                    println!("pid \"{pid:?}\" not found");
276                                }
277                            }
278                        } else {
279                            let proc_name = tmp[1];
280                            for proc_ in sys.processes_by_name(proc_name.as_ref()) {
281                                println!("==== {} ====", proc_.name().to_string_lossy());
282                                println!("{proc_:?}");
283                            }
284                        }
285                    }
286                    Err(error) => {
287                        println!("System information cannot be retrieved: {error}");
288                    }
289                }
290            }
291        }
292        "temperature" => match components {
293            Ok(components) => {
294                for component in components.iter() {
295                    println!("{component:?}");
296                }
297            }
298            Err(error) => {
299                println!("Components information cannot be retrieved: {error}");
300            }
301        },
302        "network" => match networks {
303            Ok(networks) => {
304                for (interface_name, data) in networks.iter() {
305                    println!(
306                        "\
307    {}:
308      operational state {}
309      ether {}
310      input data  (new / total): {} / {} B
311      output data (new / total): {} / {} B",
312                        interface_name.display(),
313                        data.operational_state(),
314                        data.mac_address(),
315                        data.received(),
316                        data.total_received(),
317                        data.transmitted(),
318                        data.total_transmitted(),
319                    );
320                }
321            }
322            Err(error) => {
323                println!("Networks information cannot be retrieved: {error}");
324            }
325        },
326        "show" => {
327            println!("'show' command expects a pid number or a process name");
328        }
329        e if e.starts_with("kill ") => {
330            let tmp: Vec<&str> = e
331                .split(' ')
332                .map(|s| s.trim())
333                .filter(|s| !s.is_empty())
334                .collect();
335
336            if tmp.len() != 3 {
337                println!("kill command takes the pid and a signal number in parameter!");
338                println!("example: kill 1254 9");
339            } else {
340                let Ok(pid) = Pid::from_str(tmp[1]) else {
341                    eprintln!("Expected a number for the PID, found {:?}", tmp[1]);
342                    return false;
343                };
344                let Ok(signal) = usize::from_str(tmp[2]) else {
345                    eprintln!("Expected a number for the signal, found {:?}", tmp[2]);
346                    return false;
347                };
348                let Some(signal) = SUPPORTED_SIGNALS.get(signal) else {
349                    eprintln!(
350                        "No signal matching {signal}. Use the `signals` command to get the \
351                         list of signals.",
352                    );
353                    return false;
354                };
355
356                match sys {
357                    Ok(sys) => match sys.process(pid) {
358                        Some(p) => {
359                            if let Some(res) = p.kill_with(*signal) {
360                                println!("kill: {res}");
361                            } else {
362                                eprintln!("kill: signal not supported on this platform");
363                            }
364                        }
365                        None => {
366                            eprintln!("pid not found");
367                        }
368                    },
369                    Err(error) => {
370                        println!("System information cannot be retrieved: {error}");
371                    }
372                }
373            }
374        }
375        "disks" => match disks {
376            Ok(disks) => {
377                for disk in disks {
378                    println!("{disk:?}");
379                }
380            }
381            Err(error) => {
382                println!("Disks information cannot be retrieved: {error}");
383            }
384        },
385        "users" => match users {
386            Ok(users) => {
387                for user in users {
388                    println!("{:?} => {:?}", user.name(), user.groups());
389                }
390            }
391            Err(error) => {
392                println!("Users information cannot be retrieved: {error}");
393            }
394        },
395        "groups" => match Groups::new_with_refreshed_list() {
396            Ok(groups) => {
397                for group in &groups {
398                    println!("{group:?}");
399                }
400            }
401            Err(error) => {
402                println!("Groups information cannot be retrieved: {error}");
403            }
404        },
405        "boot_time" => match System::boot_time() {
406            Ok(boot_time) => println!("{boot_time} seconds"),
407            Err(error) => eprintln!("Failed to get `boot_time`: {error}"),
408        },
409        "uptime" => match System::uptime() {
410            Ok(up) => {
411                let mut uptime = up;
412                let days = uptime / 86400;
413                uptime -= days * 86400;
414                let hours = uptime / 3600;
415                uptime -= hours * 3600;
416                let minutes = uptime / 60;
417                println!("{days} days {hours} hours {minutes} minutes ({up} seconds in total)");
418            }
419            Err(error) => eprintln!("Failed to get `uptime`: {error}"),
420        },
421        x if x.starts_with("refresh") => {
422            if x == "refresh" {
423                match sys {
424                    Ok(sys) => {
425                        println!("Getting processes' information...");
426                        sys.refresh_all();
427                        println!("Done.");
428                    }
429                    Err(error) => {
430                        println!("System information cannot be retrieved: {error}");
431                    }
432                }
433            } else if x.starts_with("refresh ") {
434                println!("Getting process' information...");
435                if let Some(pid) = x
436                    .split(' ')
437                    .filter_map(|pid| pid.parse().ok())
438                    .take(1)
439                    .next()
440                {
441                    match sys {
442                        Ok(sys) => {
443                            if sys.refresh_processes_specifics(
444                                sysinfo::ProcessesToUpdate::Some(&[pid]),
445                                true,
446                                ProcessRefreshKind::everything(),
447                            ) != 0
448                            {
449                                println!("Process `{pid}` updated successfully");
450                            } else {
451                                println!("Process `{pid}` couldn't be updated...");
452                            }
453                        }
454                        Err(error) => {
455                            println!("System information cannot be retrieved: {error}");
456                        }
457                    }
458                } else {
459                    println!("Invalid [pid] received...");
460                }
461            } else {
462                println!(
463                    "\"{x}\": Unknown command. Enter 'help' if you want to get the commands' \
464                     list.",
465                );
466            }
467        }
468        "pid" => {
469            println!(
470                "PID: {}",
471                sysinfo::get_current_pid().expect("failed to get PID")
472            );
473        }
474        "system" => {
475            println!(
476                "System name:              {}\n\
477                 System kernel version:    {}\n\
478                 System OS version:        {}\n\
479                 System OS (long) version: {}\n\
480                 System host name:         {}\n\
481                 System kernel:            {}",
482                System::name().unwrap_or_else(|_| "<unknown>".to_owned()),
483                System::kernel_version().unwrap_or_else(|_| "<unknown>".to_owned()),
484                System::os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
485                System::long_os_version().unwrap_or_else(|_| "<unknown>".to_owned()),
486                System::host_name().unwrap_or_else(|_| "<unknown>".to_owned()),
487                System::kernel_long_version().unwrap_or_else(|_| "<unknown>".to_owned()),
488            );
489        }
490        "motherboard" => match Motherboard::new() {
491            Ok(m) => println!("{m:#?}"),
492            Err(error) => println!("Cannot retrieve motherboard information: {error:?}"),
493        },
494        "product" => {
495            println!("{:#?}", Product);
496        }
497        e => {
498            println!(
499                "\"{e}\": Unknown command. Enter 'help' if you want to get the commands' \
500                 list.",
501            );
502        }
503    }
504    false
505}
1.0.0

pub fn windows(&self, size: usize) -> Windows<'_, T> ⓘ

Returns an iterator over all contiguous windows of length size. The windows overlap. If the slice is shorter than size, the iterator returns no values.

§Panics

Panics if size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.windows(3);
assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
assert!(iter.next().is_none());

If the slice is shorter than size:

let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());

Because the [Iterator] trait cannot represent the required lifetimes, there is no windows_mut analog to windows; [0,1,2].windows_mut(2).collect() would violate the rules of references (though a LendingIterator analog is possible). You can sometimes use Cell::as_slice_of_cells in conjunction with windows instead:

use std::cell::Cell;

let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
let slice = &mut array[..];
let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
for w in slice_of_cells.windows(3) {
    Cell::swap(&w[0], &w[2]);
}
assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1.0.0

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> ⓘ

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert_eq!(iter.next().unwrap(), &['m']);
assert!(iter.next().is_none());
1.31.0

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> ⓘ

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks.

See chunks for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
1.88.0

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

Splits the slice into a slice of N-element arrays, assuming that there’s no remainder.

This is the inverse operation to as_flattened.

As this is unsafe, consider whether you could use as_chunks or as_rchunks instead, perhaps via something like if let (chunks, []) = slice.as_chunks() or let (chunks, []) = slice.as_chunks() else { unreachable!() };.

§Safety

This may only be called when

  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • N != 0.
§Examples
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
    // SAFETY: 1-element chunks never have remainder
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
    // SAFETY: The slice length (6) is a multiple of 3
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);

// These would be unsound:
// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
1.88.0

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

Splits the slice into a slice of N-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N.

The remainder is meaningful in the division sense. Given let (chunks, remainder) = slice.as_chunks(), then:

  • chunks.len() equals slice.len() / N,
  • remainder.len() equals slice.len() % N, and
  • slice.len() equals chunks.len() * N + remainder.len().

You can flatten the chunks back into a slice-of-T with as_flattened.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let (chunks, remainder) = slice.as_chunks();
assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
assert_eq!(remainder, &['m']);

If you expect the slice to be an exact multiple, you can combine let-else with an empty slice pattern:

let slice = ['R', 'u', 's', 't'];
let (chunks, []) = slice.as_chunks::<2>() else {
    panic!("slice didn't have even length")
};
assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1.88.0

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

Splits the slice into a slice of N-element arrays, starting at the end of the slice, and a remainder slice with length strictly less than N.

The remainder is meaningful in the division sense. Given let (remainder, chunks) = slice.as_rchunks(), then:

  • remainder.len() equals slice.len() % N,
  • chunks.len() equals slice.len() / N, and
  • slice.len() equals chunks.len() * N + remainder.len().

You can flatten the chunks back into a slice-of-T with as_flattened.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let (remainder, chunks) = slice.as_rchunks();
assert_eq!(remainder, &['l']);
assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
1.94.0

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> ⓘ

Returns an iterator over overlapping windows of N elements of a slice, starting at the beginning of the slice.

This is the const generic equivalent of windows.

If N is greater than the size of the slice, it will return no windows.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = [0, 1, 2, 3];
let mut iter = slice.array_windows();
assert_eq!(iter.next().unwrap(), &[0, 1]);
assert_eq!(iter.next().unwrap(), &[1, 2]);
assert_eq!(iter.next().unwrap(), &[2, 3]);
assert!(iter.next().is_none());
1.31.0

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> ⓘ

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See rchunks_exact for a variant of this iterator that returns chunks of always exactly chunk_size elements, and chunks for the same iterator but starting at the beginning of the slice.

If your chunk_size is a constant, consider using as_rchunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert_eq!(iter.next().unwrap(), &['l']);
assert!(iter.next().is_none());
1.31.0

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> ⓘ

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of rchunks.

See rchunks for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact for the same iterator but starting at the beginning of the slice.

If your chunk_size is a constant, consider using as_rchunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks_exact(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['l']);
1.77.0

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F> ⓘ
where F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs of elements using the predicate to separate them.

The predicate is called for every pair of consecutive elements, meaning that it is called on slice[0] and slice[1], followed by slice[1] and slice[2], and so on.

§Examples
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.chunk_by(|a, b| a == b);

assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);

This method can be used to extract the sorted subslices:

let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];

let mut iter = slice.chunk_by(|a, b| a <= b);

assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
assert_eq!(iter.next(), None);
1.0.0

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

§Panics

Panics if mid > len. For a non-panicking alternative see split_at_checked.

§Examples
let v = ['a', 'b', 'c'];

{
   let (left, right) = v.split_at(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

{
    let (left, right) = v.split_at(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

{
    let (left, right) = v.split_at(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.79.0

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len().

§Examples
let v = ['a', 'b', 'c'];

unsafe {
   let (left, right) = v.split_at_unchecked(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.80.0

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is too short.

If mid ≤ len, returns a pair of slices where the first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Otherwise, if mid > len, returns None.

§Examples
let v = [1, -2, 3, -4, 5, -6];

{
   let (left, right) = v.split_at_checked(0).unwrap();
   assert_eq!(left, []);
   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(2).unwrap();
    assert_eq!(left, [1, -2]);
    assert_eq!(right, [3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(6).unwrap();
    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
    assert_eq!(right, []);
}

assert_eq!(None, v.split_at_checked(7));
1.0.0

pub fn split<F>(&self, pred: F) -> Split<'_, T, F> ⓘ
where F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match pred. The matched element is not contained in the subslices.

§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

If the first element is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last element in the slice is matched, an empty slice will be the last item returned by the iterator:

let slice = [10, 40, 33];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[]);
assert!(iter.next().is_none());

If two matched elements are directly adjacent, an empty slice will be present between them:

let slice = [10, 6, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10]);
assert_eq!(iter.next().unwrap(), &[]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
1.51.0

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F> ⓘ
where F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match pred. The matched element is contained in the end of the previous subslice as a terminator.

§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

If the last element of the slice is matched, that element will be considered the terminator of the preceding slice. That slice will be the last item returned by the iterator.

let slice = [3, 10, 40, 33];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[3]);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert!(iter.next().is_none());
1.27.0

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F> ⓘ
where F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match pred, starting at the end of the slice and working backwards. The matched element is not contained in the subslices.

§Examples
let slice = [11, 22, 33, 0, 44, 55];
let mut iter = slice.rsplit(|num| *num == 0);

assert_eq!(iter.next().unwrap(), &[44, 55]);
assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
assert_eq!(iter.next(), None);

As with split(), if the first or last element is matched, an empty slice will be the first (or last) item returned by the iterator.

let v = &[0, 1, 1, 2, 3, 5, 8];
let mut it = v.rsplit(|n| *n % 2 == 0);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next().unwrap(), &[3, 5]);
assert_eq!(it.next().unwrap(), &[1, 1]);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next(), None);
1.0.0

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F> ⓘ
where F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match pred, limited to returning at most n items. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

§Examples

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], [20, 60, 50]):

let v = [10, 40, 30, 20, 60, 50];

for group in v.splitn(2, |num| *num % 3 == 0) {
    println!("{group:?}");
}
1.0.0

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F> ⓘ
where F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match pred limited to returning at most n items. This starts at the end of the slice and works backwards. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

§Examples

Print the slice split once, starting from the end, by numbers divisible by 3 (i.e., [50], [10, 40, 30, 20]):

let v = [10, 40, 30, 20, 60, 50];

for group in v.rsplitn(2, |num| *num % 3 == 0) {
    println!("{group:?}");
}
1.101.0

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where F: FnMut(&T) -> bool,

Splits the slice on the first element that matches the specified predicate.

If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None.

§Examples
let s = [1, 2, 3, 2, 4];
assert_eq!(s.split_once(|&x| x == 2), Some((
    &[1][..],
    &[3, 2, 4][..]
)));
assert_eq!(s.split_once(|&x| x == 0), None);
1.101.0

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where F: FnMut(&T) -> bool,

Splits the slice on the last element that matches the specified predicate.

If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None.

§Examples
let s = [1, 2, 3, 2, 4];
assert_eq!(s.rsplit_once(|&x| x == 2), Some((
    &[1, 2, 3][..],
    &[4][..]
)));
assert_eq!(s.rsplit_once(|&x| x == 0), None);
1.0.0

pub fn contains(&self, x: &T) -> bool
where T: PartialEq,

Returns true if the slice contains an element with the given value.

This operation is O(n).

Note that if you have a sorted slice, binary_search may be faster.

§Examples
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));

If you do not have a &T, but some other value that you can compare with one (for example, String implements PartialEq<str>), you can use iter().any:

let v = [String::from("hello"), String::from("world")]; // slice of `String`
assert!(v.iter().any(|e| e == "hello")); // search with `&str`
assert!(!v.iter().any(|e| e == "hi"));
1.0.0

pub fn starts_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(v.starts_with(&v));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
1.0.0

pub fn ends_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(v.ends_with(&v));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
1.51.0

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

Returns a subslice with the prefix removed.

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. If prefix is empty, simply returns the original slice. If prefix is equal to the original slice, returns an empty slice.

If the slice does not start with prefix, returns None.

§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_prefix(&[50]), None);
assert_eq!(v.strip_prefix(&[10, 50]), None);

let prefix : &str = "he";
assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
           Some(b"llo".as_ref()));
1.51.0

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

Returns a subslice with the suffix removed.

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. If suffix is empty, simply returns the original slice. If suffix is equal to the original slice, returns an empty slice.

If the slice does not end with suffix, returns None.

§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_suffix(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);
1.98.0

pub fn strip_circumfix<S, P>(&self, prefix: &P, suffix: &S) -> Option<&[T]>
where T: PartialEq, S: SlicePattern<Item = T> + ?Sized, P: SlicePattern<Item = T> + ?Sized,

Returns a subslice with the prefix and suffix removed.

If the slice starts with prefix, ends with suffix, and the prefix and suffix don’t overlap, returns the subslice after the prefix and before the suffix, wrapped in Some.

If the slice does not start with prefix, does not end with suffix, or the prefix and suffix overlap in the slice, returns None.

§Examples
let v = &[10, 50, 40, 30];
assert_eq!(v.strip_circumfix(&[10], &[30]), Some(&[50, 40][..]));
assert_eq!(v.strip_circumfix(&[10], &[40, 30]), Some(&[50][..]));
assert_eq!(v.strip_circumfix(&[10, 50], &[40, 30]), Some(&[][..]));
assert_eq!(v.strip_circumfix(&[50], &[30]), None);
assert_eq!(v.strip_circumfix(&[10], &[40]), None);
assert_eq!(v.strip_circumfix(&[], &[40, 30]), Some(&[10, 50][..]));
assert_eq!(v.strip_circumfix(&[10, 50], &[]), Some(&[40, 30][..]));
assert_eq!(v.strip_circumfix(&[10, 50, 40], &[50, 40, 30]), None);
1.100.0

pub fn trim_prefix<P>(&self, prefix: &P) -> &[T]
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

Returns a subslice with the optional prefix removed.

If the slice starts with prefix, returns the subslice after the prefix. If prefix is empty or the slice does not start with prefix, simply returns the original slice. If prefix is equal to the original slice, returns an empty slice.

§Examples
let v = &[10, 40, 30];

// Prefix present - removes it
assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]);
assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]);

// Prefix absent - returns original slice
assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]);

let prefix : &str = "he";
assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref());
1.100.0

pub fn trim_suffix<P>(&self, suffix: &P) -> &[T]
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

Returns a subslice with the optional suffix removed.

If the slice ends with suffix, returns the subslice before the suffix. If suffix is empty or the slice does not end with suffix, simply returns the original slice. If suffix is equal to the original slice, returns an empty slice.

§Examples
let v = &[10, 40, 30];

// Suffix present - removes it
assert_eq!(v.trim_suffix(&[30]), &[10, 40][..]);
assert_eq!(v.trim_suffix(&[40, 30]), &[10][..]);
assert_eq!(v.trim_suffix(&[10, 40, 30]), &[][..]);

// Suffix absent - returns original slice
assert_eq!(v.trim_suffix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_suffix(&[50, 30]), &[10, 40, 30][..]);

Binary searches this slice for a given element. If the slice is not sorted, the returned result is unspecified and meaningless.

If the value is found then [Result::Ok] is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then [Result::Err] is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search_by, binary_search_by_key, and partition_point.

§Examples

Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

assert_eq!(s.binary_search(&13),  Ok(9));
assert_eq!(s.binary_search(&4),   Err(7));
assert_eq!(s.binary_search(&100), Err(13));
let r = s.binary_search(&1);
assert!(match r { Ok(1..=4) => true, _ => false, });

If you want to find that whole range of matching items, rather than an arbitrary matching one, that can be done using partition_point:

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let low = s.partition_point(|x| x < &1);
assert_eq!(low, 1);
let high = s.partition_point(|x| x <= &1);
assert_eq!(high, 5);
let r = s.binary_search(&1);
assert!((low..high).contains(&r.unwrap()));

assert!(s[..low].iter().all(|&x| x < 1));
assert!(s[low..high].iter().all(|&x| x == 1));
assert!(s[high..].iter().all(|&x| x > 1));

// For something not found, the "range" of equal items is empty
assert_eq!(s.partition_point(|x| x < &11), 9);
assert_eq!(s.partition_point(|x| x <= &11), 9);
assert_eq!(s.binary_search(&11), Err(9));

If you want to insert an item to a sorted vector, while maintaining sort order, consider using partition_point:

let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
// to shift less elements.
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.0.0

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

The comparator function should return an order code that indicates whether its argument is Less, Equal or Greater the desired target. If the slice is not sorted or if the comparator function does not implement an order consistent with the sort order of the underlying slice, the returned result is unspecified and meaningless.

If the value is found then [Result::Ok] is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then [Result::Err] is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by_key, and partition_point.

§Examples

Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });
1.10.0

pub fn binary_search_by_key<'a, B, F>( &'a self, b: &B, f: F, ) -> Result<usize, usize>
where F: FnMut(&'a T) -> B, B: Ord,

Binary searches this slice with a key extraction function.

Assumes that the slice is sorted by the key, for instance with sort_by_key using the same key extraction function. If the slice is not sorted by the key, the returned result is unspecified and meaningless.

If the value is found then [Result::Ok] is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then [Result::Err] is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by, and partition_point.

§Examples

Looks up a series of four elements in a slice of pairs sorted by their second elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
         (1, 21), (2, 34), (4, 55)];

assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });
1.30.0

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmutes the slice to a slice of another type, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. The middle part will be as big as possible under the given alignment constraint and element size.

This method has no purpose when either input element T or output element U are zero-sized and will return the original slice without splitting anything.

§Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

§Examples

Basic usage:

unsafe {
    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
    // less_efficient_algorithm_for_bytes(prefix);
    // more_efficient_algorithm_for_aligned_shorts(shorts);
    // less_efficient_algorithm_for_bytes(suffix);
}

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where Simd<T, LANES>: AsRef<[T; LANES]>, T: SimdElement,

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

Splits a slice into a prefix, a middle of aligned SIMD types, and a suffix.

This is a safe wrapper around [slice::align_to], so inherits the same guarantees as that method.

§Panics

This will panic if the size of the SIMD type is different from LANES times that of the scalar.

At the time of writing, the trait restrictions on Simd<T, LANES> keeps that from ever happening, as only power-of-two numbers of lanes are supported. It’s possible that, in the future, those restrictions might be lifted in a way that would make it possible to see panics from this method for something like LANES == 3.

§Examples
#![feature(portable_simd)]
use core::simd::prelude::*;

let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); // Not enough elements for anything in the middle

// They might be split in any possible way between prefix and suffix
let it = prefix.iter().chain(suffix).copied();
assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);

fn basic_simd_sum(x: &[f32]) -> f32 {
    use std::ops::Add;
    let (prefix, middle, suffix) = x.as_simd();
    let sums = f32x4::from_array([
        prefix.iter().copied().sum(),
        0.0,
        0.0,
        suffix.iter().copied().sum(),
    ]);
    let sums = middle.iter().copied().fold(sums, f32x4::add);
    sums.reduce_sum()
}

let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
1.82.0

pub fn is_sorted(&self) -> bool
where T: PartialOrd,

Checks if the elements of this slice are sorted.

That is, for each element a and its following element b, a <= b must hold. If the slice yields exactly zero or one element, true is returned.

Note that if Self::Item is only PartialOrd, but not Ord, the above definition implies that this function returns false if any two consecutive items are not comparable.

§Examples
let empty: [i32; 0] = [];

assert!([1, 2, 2, 9].is_sorted());
assert!(![1, 3, 2, 4].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());
1.82.0

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where F: FnMut(&'a T, &'a T) -> bool,

Checks if the elements of this slice are sorted using the given comparator function.

Instead of using PartialOrd::partial_cmp, this function uses the given compare function to determine whether two elements are to be considered in sorted order.

§Examples
assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));

assert!([0].is_sorted_by(|a, b| true));
assert!([0].is_sorted_by(|a, b| false));

let empty: [i32; 0] = [];
assert!(empty.is_sorted_by(|a, b| false));
assert!(empty.is_sorted_by(|a, b| true));
1.82.0

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where F: FnMut(&'a T) -> K, K: PartialOrd,

Checks if the elements of this slice are sorted using the given key extraction function.

Instead of comparing the slice’s elements directly, this function compares the keys of the elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its documentation for more information.

§Examples
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1.52.0

pub fn partition_point<P>(&self, pred: P) -> usize
where P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate (the index of the first element of the second partition).

The slice is assumed to be partitioned according to the given predicate. This means that all elements for which the predicate returns true are at the start of the slice and all elements for which the predicate returns false are at the end. For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 (all odd numbers are at the start, all even at the end).

If this slice is not partitioned, the returned result is unspecified and meaningless, as this method performs a kind of binary search.

See also binary_search, binary_search_by, and binary_search_by_key.

§Examples
let v = [1, 2, 3, 3, 5, 6, 7];
let i = v.partition_point(|&x| x < 5);

assert_eq!(i, 4);
assert!(v[..i].iter().all(|&x| x < 5));
assert!(v[i..].iter().all(|&x| !(x < 5)));

If all elements of the slice match the predicate, including if the slice is empty, then the length of the slice will be returned:

let a = [2, 4, 8];
assert_eq!(a.partition_point(|x| x < &100), a.len());
let a: [i32; 0] = [];
assert_eq!(a.partition_point(|x| x < &100), 0);

If you want to insert an item to a sorted vector, while maintaining sort order:

let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.94.0

pub fn element_offset(&self, element: &T) -> Option<usize>

Returns the index that an element reference points to.

Returns None if element does not point to the start of an element within the slice.

This method is useful for extending slice iterators like [slice::split].

Note that this uses pointer arithmetic and does not compare elements. To find the index of an element via comparison, use .iter().position() instead.

§Panics

Panics if T is zero-sized.

§Examples

Basic usage:

let nums: &[u32] = &[1, 7, 1, 1];
let num = &nums[2];

assert_eq!(num, &1);
assert_eq!(nums.element_offset(num), Some(2));

Returning None with an unaligned element:

let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
let flat_arr: &[u32] = arr.as_flattened();

let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();

assert_eq!(ok_elm, &[0, 1]);
assert_eq!(weird_elm, &[1, 2]);

assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0
assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1
1.98.0

pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>>

Returns the range of indices that a subslice points to.

Returns None if subslice does not point within the slice or if it is not aligned with the elements in the slice.

This method does not compare elements. Instead, this method finds the location in the slice that subslice was obtained from. To find the index of a subslice via comparison, instead use .windows().position().

This method is useful for extending slice iterators like [slice::split].

Note that this may return a false positive (either Some(0..0) or Some(self.len()..self.len())) if subslice has a length of zero and points to the beginning or end of another, separate, slice.

§Panics

Panics if T is zero-sized.

§Examples

Basic usage:

use core::range::Range;

let nums = &[0, 5, 10, 0, 0, 5];

let mut iter = nums
    .split(|t| *t == 0)
    .map(|n| nums.subslice_range(n).unwrap());

assert_eq!(iter.next(), Some(Range { start: 0, end: 0 }));
assert_eq!(iter.next(), Some(Range { start: 1, end: 3 }));
assert_eq!(iter.next(), Some(Range { start: 4, end: 4 }));
assert_eq!(iter.next(), Some(Range { start: 5, end: 6 }));

pub fn as_slice(&self) -> &[T]

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

Returns the same slice &[T].

This method is redundant when used directly on &[T], but it helps dereferencing other “container” types to slices, for example Box<[T]> or Arc<[T]>.

1.0.0

pub fn to_vec(&self) -> Vec<T>
where T: Clone,

Copies self into a new Vec.

§Examples
let s = [10, 40, 30];
let x = s.to_vec();
// Here, `s` and `x` can be modified independently.

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where A: Allocator, T: Clone,

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

Copies self into a new Vec with an allocator.

§Examples
#![feature(allocator_ext)]

use std::alloc::System;

let s = [10, 40, 30];
let x = s.to_vec_in(System);
// Here, `s` and `x` can be modified independently.
1.40.0

pub fn repeat(&self, n: usize) -> Vec<T>
where T: Copy,

Creates a vector by copying a slice n times.

§Panics

This function will panic if the capacity would overflow.

§Examples
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);

A panic upon overflow:

ⓘ
// this will panic at runtime
b"0123456789abcdef".repeat(usize::MAX);
1.0.0

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output ⓘ
where [T]: Concat<Item>, Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

§Examples
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
1.3.0

pub fn join<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output ⓘ
where [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a given separator between each.

§Examples
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
1.0.0

pub fn connect<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output ⓘ
where [T]: Join<Separator>,

👎Deprecated since 1.3.0:

renamed to join

Flattens a slice of T into a single value Self::Output, placing a given separator between each.

§Examples
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);

Trait Implementations§

Source§

impl Debug for Gpus

Available on crate feature gpu only.
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for Gpus

Source§

type Target = [Gpu]

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<'a> IntoIterator for &'a Gpus

Source§

type Item = &'a Gpu

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'a, Gpu>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl Serialize for Gpus

Available on crate feature gpu only.
Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl !Send for Gpus

§

impl !Sync for Gpus

§

impl Freeze for Gpus

§

impl RefUnwindSafe for Gpus

§

impl Unpin for Gpus

§

impl UnsafeUnpin for Gpus

§

impl UnwindSafe for Gpus

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = !

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.