aboutsummaryrefslogtreecommitdiff
path: root/src/string.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/string.zig163
1 files changed, 159 insertions, 4 deletions
diff --git a/src/string.zig b/src/string.zig
index f09428f69..cf4109d40 100644
--- a/src/string.zig
+++ b/src/string.zig
@@ -250,6 +250,15 @@ pub const String = extern struct {
return BunString__fromBytes(bytes.ptr, bytes.len);
}
+ pub fn isEmpty(this: String) bool {
+ return this.tag == .Empty or this.length() == 0;
+ }
+
+ pub fn dupeRef(this: String) String {
+ this.ref();
+ return this;
+ }
+
pub fn initWithType(comptime Type: type, value: Type) String {
switch (comptime Type) {
ZigString => return String{ .tag = .ZigString, .value = .{ .ZigString = value } },
@@ -337,6 +346,24 @@ pub const String = extern struct {
return BunString__toJS(globalObject, this);
}
+ pub fn toJSConst(this: *const String, globalObject: *bun.JSC.JSGlobalObject) JSC.JSValue {
+ JSC.markBinding(@src());
+ var a = this.*;
+ return toJS(&a, globalObject);
+ }
+
+ extern fn BunString__createArray(
+ globalObject: *bun.JSC.JSGlobalObject,
+ ptr: [*]const String,
+ len: usize,
+ ) JSC.JSValue;
+
+ pub fn toJSArray(globalObject: *bun.JSC.JSGlobalObject, array: []const bun.String) JSC.JSValue {
+ JSC.markBinding(@src());
+
+ return BunString__createArray(globalObject, array.ptr, array.len);
+ }
+
pub fn toZigString(this: String) ZigString {
if (this.tag == .StaticZigString or this.tag == .ZigString) {
return this.value.ZigString;
@@ -449,6 +476,13 @@ pub const String = extern struct {
return ZigString.Slice.empty;
}
+ pub fn toSlice(this: String, allocator: std.mem.Allocator) SliceWithUnderlyingString {
+ return SliceWithUnderlyingString{
+ .utf8 = this.toUTF8(allocator),
+ .underlying = this,
+ };
+ }
+
extern fn BunString__fromJS(globalObject: *JSC.JSGlobalObject, value: bun.JSC.JSValue, out: *String) bool;
extern fn BunString__toJS(globalObject: *JSC.JSGlobalObject, in: *String) JSC.JSValue;
extern fn BunString__toWTFString(this: *String) void;
@@ -473,11 +507,114 @@ pub const String = extern struct {
return this.toZigString().eqlComptime(value);
}
+ pub fn is8Bit(this: String) bool {
+ return switch (this.tag) {
+ .WTFStringImpl => this.value.WTFStringImpl.is8Bit(),
+ .ZigString => !this.value.ZigString.is16Bit(),
+ else => true,
+ };
+ }
+
+ pub fn indexOfComptimeWithCheckLen(this: String, comptime values: []const []const u8, comptime check_len: usize) ?usize {
+ if (this.is8Bit()) {
+ const bytes = this.byteSlice();
+ for (values, 0..) |val, i| {
+ if (bun.strings.eqlComptimeCheckLenWithType(u8, bytes, val, check_len)) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
+ const u16_bytes = this.byteSlice();
+ inline for (values, 0..) |val, i| {
+ if (bun.strings.eqlComptimeCheckLenWithType(u16, u16_bytes, comptime bun.strings.toUTF16Literal(val), check_len)) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
+ pub fn indexOfComptimeArrayAssumeSameLength(this: String, comptime values: []const []const u8) ?usize {
+ if (this.is8Bit()) {
+ const bytes = this.byteSlice();
+
+ inline for (0..values.len) |i| {
+ std.debug.assert(bytes.len == values[i].len);
+ if (bun.strings.eqlComptimeCheckLenWithType(u8, bytes, values[i], false)) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
+ const u16_bytes = this.utf16();
+ var buffer: [values[0].len]u8 = undefined;
+ inline for (0..values[0].len) |i| {
+ const uchar = u16_bytes[i];
+ if (uchar > 255)
+ return null;
+
+ buffer[i] = @intCast(u8, uchar);
+ }
+
+ inline for (0..values.len) |i| {
+ if (bun.strings.eqlComptimeCheckLenWithType(u8, &buffer, values[i], false)) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
+ pub fn inMap(this: String, comptime ComptimeStringMap: anytype) ?ComptimeStringMap.Value {
+ return ComptimeStringMap.getWithEqlList(this, indexOfComptimeArrayAssumeSameLength);
+ }
+
+ pub fn inMapCaseInsensitive(this: String, comptime ComptimeStringMap: anytype) ?ComptimeStringMap.Value {
+ return ComptimeStringMap.getWithEqlList(this, indexOfComptimeArrayCaseInsensitiveSameLength);
+ }
+
+ pub fn indexOfComptimeArrayCaseInsensitiveSameLength(this: String, comptime values: []const []const u8) ?usize {
+ if (this.is8Bit()) {
+ const bytes = this.byteSlice();
+
+ inline for (0..values.len) |i| {
+ std.debug.assert(bytes.len == values[i].len);
+ if (bun.strings.eqlCaseInsensitiveASCIIIgnoreLength(bytes, values[i])) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
+ const u16_bytes = this.utf16();
+ const buffer: [values[0].len]u8 = brk: {
+ var bytes: [values[0].len]u8 = undefined;
+ for (&bytes, u16_bytes) |*byte, uchar| {
+ if (uchar > 255)
+ return null;
+
+ byte.* = @intCast(u8, uchar);
+ }
+ break :brk bytes;
+ };
+
+ inline for (0..values.len) |i| {
+ if (bun.strings.eqlCaseInsensitiveASCIIIgnoreLength(&buffer, values[i])) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+
pub fn hasPrefixComptime(this: String, comptime value: []const u8) bool {
- _ = value;
- _ = this;
- return false;
- // return this.toZigString().substring(0, value.len).eqlComptime(value);
+ return this.toZigString().substring(0, value.len).eqlComptime(value);
}
pub fn isWTFAllocator(this: std.mem.Allocator) bool {
@@ -492,3 +629,21 @@ pub const String = extern struct {
return this.toZigString().eql(other.toZigString());
}
};
+
+pub const SliceWithUnderlyingString = struct {
+ utf8: ZigString.Slice,
+ underlying: String,
+
+ pub fn deinit(this: SliceWithUnderlyingString) void {
+ this.utf8.deinit();
+ this.underlying.deref();
+ }
+
+ pub fn slice(this: SliceWithUnderlyingString) []const u8 {
+ return this.utf8.slice();
+ }
+
+ pub fn toJS(this: SliceWithUnderlyingString, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
+ return this.underlying.toJS(globalObject);
+ }
+};