Skip to content

Commit

Permalink
Merge pull request #938 from schungx/master
Browse files Browse the repository at this point in the history
Optimize string slice.
  • Loading branch information
schungx authored Dec 2, 2024
2 parents 801c2ad + ae6e9d4 commit 1dd04cd
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Rhai Release Notes
==================

Version 1.21.0
==============

Enhancements
------------

* If a string slice refers to the entire string, the slice is not cloned but returned as-is.


Version 1.20.0
==============

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = [".", "codegen"]

[package]
name = "rhai"
version = "1.20.0"
version = "1.21.0"
rust-version = "1.66.0"
edition = "2018"
resolver = "2"
Expand Down
49 changes: 39 additions & 10 deletions src/eval/chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ impl Engine {

#[cfg(not(feature = "no_index"))]
Dynamic(Union::Str(s, ..)) => {
// Numeric index - character
match idx.as_int() {
Ok(index) => {
let (ch, offset) = if index >= 0 {
Expand Down Expand Up @@ -362,11 +363,29 @@ impl Engine {
index: offset,
})
}

// Range index on empty string - empty slice
Err(typ)
if (typ == std::any::type_name::<ExclusiveRange>()
|| typ == std::any::type_name::<InclusiveRange>())
&& s.is_empty() =>
{
let value = s.clone().into();
Ok(Target::StringSlice {
source: target,
value,
start: 0,
end: 0,
exclusive: true,
})
}

// Range index - slice
Err(typ) if typ == std::any::type_name::<ExclusiveRange>() => {
// val_str[range]
let idx = idx.read_lock::<ExclusiveRange>().unwrap();
let range = &*idx;
let range = idx.read_lock::<ExclusiveRange>().unwrap().clone();
let chars_count = s.chars().count();

let start = if range.start >= 0 {
range.start as usize
} else {
Expand All @@ -383,22 +402,26 @@ impl Engine {
.unwrap_or(0)
};

let take = if end > start { end - start } else { 0 };
let value = s.chars().skip(start).take(take).collect::<String>();
let value = if start == 0 && end >= chars_count {
s.clone().into()
} else {
let take = if end > start { end - start } else { 0 };
s.chars().skip(start).take(take).collect::<String>().into()
};

Ok(Target::StringSlice {
source: target,
value: value.into(),
value,
start,
end,
exclusive: true,
})
}
Err(typ) if typ == std::any::type_name::<InclusiveRange>() => {
// val_str[range]
let idx = idx.read_lock::<InclusiveRange>().unwrap();
let range = &*idx;
let range = idx.read_lock::<InclusiveRange>().unwrap().clone();
let chars_count = s.chars().count();

let start = if *range.start() >= 0 {
*range.start() as usize
} else {
Expand All @@ -415,17 +438,23 @@ impl Engine {
.unwrap_or(0)
};

let take = if end > start { end - start + 1 } else { 0 };
let value = s.chars().skip(start).take(take).collect::<String>();
let value = if start == 0 && end >= chars_count - 1 {
s.clone().into()
} else {
let take = if end > start { end - start + 1 } else { 0 };
s.chars().skip(start).take(take).collect::<String>().into()
};

Ok(Target::StringSlice {
source: target,
value: value.into(),
value,
start,
end,
exclusive: false,
})
}

// Unsupported index type
Err(typ) => Err(self.make_type_mismatch_err::<crate::INT>(typ, idx_pos)),
}
}
Expand Down

0 comments on commit 1dd04cd

Please sign in to comment.