nushell/crates/nu-protocol/src/ast/import_pattern.rs
Daniel Buch Hansen 850ecf648a
Protocol: debug_assert!() Span to reflect a valid slice (#6806)
Also enforce this by #[non_exhaustive] span such that going forward we
cannot, in debug builds (1), construct invalid spans.

The motivation for this stems from #6431 where I've seen crashes due to
invalid slice indexing.

My hope is this will mitigate such senarios

1. https://github.com/nushell/nushell/pull/6431#issuecomment-1278147241

# Description

(description of your pull request here)

# Tests

Make sure you've done the following:

- [ ] Add tests that cover your changes, either in the command examples,
the crate/tests folder, or in the /tests folder.
- [ ] Try to think about corner cases and various ways how your changes
could break. Cover them with tests.
- [ ] If adding tests is not possible, please document in the PR body a
minimal example with steps on how to reproduce so one can verify your
change works.

Make sure you've run and fixed any issues with these commands:

- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [ ] `cargo clippy --workspace --features=extra -- -D warnings -D
clippy::unwrap_used -A clippy::needless_collect` to check that you're
using the standard code style
- [ ] `cargo test --workspace --features=extra` to check that all the
tests pass

# Documentation

- [ ] If your PR touches a user-facing nushell feature then make sure
that there is an entry in the documentation
(https://github.com/nushell/nushell.github.io) for the feature, and
update it if necessary.
2022-12-03 11:44:12 +02:00

74 lines
1.9 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{span, ModuleId, Span};
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImportPatternMember {
Glob { span: Span },
Name { name: Vec<u8>, span: Span },
List { names: Vec<(Vec<u8>, Span)> },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImportPatternHead {
pub name: Vec<u8>,
pub id: Option<ModuleId>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImportPattern {
pub head: ImportPatternHead,
pub members: Vec<ImportPatternMember>,
// communicate to eval which decls/aliases were hidden during `parse_hide()` so it does not
// interpret these as env var names:
pub hidden: HashSet<Vec<u8>>,
}
impl ImportPattern {
pub fn new() -> Self {
ImportPattern {
head: ImportPatternHead {
name: vec![],
id: None,
span: Span::unknown(),
},
members: vec![],
hidden: HashSet::new(),
}
}
pub fn span(&self) -> Span {
let mut spans = vec![self.head.span];
for member in &self.members {
match member {
ImportPatternMember::Glob { span } => spans.push(*span),
ImportPatternMember::Name { name: _, span } => spans.push(*span),
ImportPatternMember::List { names } => {
for (_, span) in names {
spans.push(*span);
}
}
}
}
span(&spans)
}
pub fn with_hidden(self, hidden: HashSet<Vec<u8>>) -> Self {
ImportPattern {
head: self.head,
members: self.members,
hidden,
}
}
}
impl Default for ImportPattern {
fn default() -> Self {
Self::new()
}
}