mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
terminal: kitty parser get a little clever, keys are always a char
This commit is contained in:
@ -7,7 +7,13 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
|
||||||
const KV = std.StringHashMapUnmanaged([]const u8);
|
/// The key-value pairs for the control information for a command. The
|
||||||
|
/// keys are always single characters and the values are either single
|
||||||
|
/// characters or 32-bit unsigned integers.
|
||||||
|
///
|
||||||
|
/// For the value of this: if the value is a single printable ASCII character
|
||||||
|
/// it is the ASCII code. Otherwise, it is parsed as a 32-bit unsigned integer.
|
||||||
|
const KV = std.AutoHashMapUnmanaged(u8, u32);
|
||||||
|
|
||||||
/// Command parser parses the Kitty graphics protocol escape sequence.
|
/// Command parser parses the Kitty graphics protocol escape sequence.
|
||||||
pub const CommandParser = struct {
|
pub const CommandParser = struct {
|
||||||
@ -18,13 +24,21 @@ pub const CommandParser = struct {
|
|||||||
/// This is the list of KV pairs that we're building up.
|
/// This is the list of KV pairs that we're building up.
|
||||||
kv: KV = .{},
|
kv: KV = .{},
|
||||||
|
|
||||||
|
/// This is used as a buffer to store the key/value of a KV pair.
|
||||||
|
/// The value of a KV pair is at most a 32-bit integer which at most
|
||||||
|
/// is 10 characters (4294967295).
|
||||||
|
kv_temp: [10]u8 = undefined,
|
||||||
|
kv_temp_len: u4 = 0,
|
||||||
|
|
||||||
|
/// Current kv key
|
||||||
|
kv_current: u8 = 0,
|
||||||
|
|
||||||
/// This is the list of bytes that contains both KV data and final
|
/// This is the list of bytes that contains both KV data and final
|
||||||
/// data. You shouldn't access this directly.
|
/// data. You shouldn't access this directly.
|
||||||
data: std.ArrayListUnmanaged(u8) = .{},
|
data: std.ArrayListUnmanaged(u8) = .{},
|
||||||
|
|
||||||
/// Internal state for parsing.
|
/// Internal state for parsing.
|
||||||
data_i: usize = 0,
|
data_i: usize = 0,
|
||||||
value_ptr: *[]const u8 = undefined,
|
|
||||||
state: State = .control_key,
|
state: State = .control_key,
|
||||||
|
|
||||||
const State = enum {
|
const State = enum {
|
||||||
@ -63,20 +77,14 @@ pub const CommandParser = struct {
|
|||||||
.control_key => switch (c) {
|
.control_key => switch (c) {
|
||||||
// '=' means the key is complete and we're moving to the value.
|
// '=' means the key is complete and we're moving to the value.
|
||||||
'=' => {
|
'=' => {
|
||||||
// We need to copy the key into the arena so that the
|
// All keys at the time of writing this parser are one char
|
||||||
// pointer is stable.
|
if (self.kv_temp_len != 1) @panic("TODO");
|
||||||
const alloc = self.arena.allocator();
|
self.kv_current = self.kv_temp[0];
|
||||||
const gop = try self.kv.getOrPut(alloc, try alloc.dupe(
|
self.kv_temp_len = 0;
|
||||||
u8,
|
|
||||||
self.data.items[self.data_i..],
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state = .control_value;
|
self.state = .control_value;
|
||||||
self.value_ptr = gop.value_ptr;
|
|
||||||
self.data_i = self.data.items.len;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
else => try self.data.append(self.arena.allocator(), c),
|
else => try self.accumulateValue(c),
|
||||||
},
|
},
|
||||||
|
|
||||||
.control_value => switch (c) {
|
.control_value => switch (c) {
|
||||||
@ -92,7 +100,7 @@ pub const CommandParser = struct {
|
|||||||
self.state = .data;
|
self.state = .data;
|
||||||
},
|
},
|
||||||
|
|
||||||
else => try self.data.append(self.arena.allocator(), c),
|
else => try self.accumulateValue(c),
|
||||||
},
|
},
|
||||||
|
|
||||||
.data => try self.data.append(self.arena.allocator(), c),
|
.data => try self.data.append(self.arena.allocator(), c),
|
||||||
@ -123,9 +131,9 @@ pub const CommandParser = struct {
|
|||||||
|
|
||||||
// Determine our action, which is always a single character.
|
// Determine our action, which is always a single character.
|
||||||
const action: u8 = action: {
|
const action: u8 = action: {
|
||||||
const str = self.kv.get("a") orelse break :action 't';
|
const value = self.kv.get('a') orelse break :action 't';
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
const c = std.math.cast(u8, value) orelse return error.InvalidFormat;
|
||||||
break :action str[0];
|
break :action c;
|
||||||
};
|
};
|
||||||
const control: Command.Control = switch (action) {
|
const control: Command.Control = switch (action) {
|
||||||
'q' => .{ .query = try Transmission.parse(self.kv) },
|
'q' => .{ .query = try Transmission.parse(self.kv) },
|
||||||
@ -143,8 +151,8 @@ pub const CommandParser = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Determine our quiet value
|
// Determine our quiet value
|
||||||
const quiet: Command.Quiet = if (self.kv.get("q")) |str| quiet: {
|
const quiet: Command.Quiet = if (self.kv.get('q')) |v| quiet: {
|
||||||
break :quiet switch (try std.fmt.parseInt(u32, str, 10)) {
|
break :quiet switch (v) {
|
||||||
0 => .no,
|
0 => .no,
|
||||||
1 => .ok,
|
1 => .ok,
|
||||||
2 => .failures,
|
2 => .failures,
|
||||||
@ -164,12 +172,31 @@ pub const CommandParser = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accumulateValue(self: *CommandParser, c: u8) !void {
|
||||||
|
self.kv_temp[self.kv_temp_len] = c;
|
||||||
|
self.kv_temp_len += 1;
|
||||||
|
if (self.kv_temp_len > self.kv_temp.len) @panic("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
fn finishValue(self: *CommandParser) !void {
|
fn finishValue(self: *CommandParser) !void {
|
||||||
self.value_ptr.* = try self.arena.allocator().dupe(
|
const alloc = self.arena.allocator();
|
||||||
u8,
|
|
||||||
self.data.items[self.data_i..self.data.items.len],
|
// Check for ASCII chars first
|
||||||
);
|
if (self.kv_temp_len == 1) {
|
||||||
self.data_i = self.data.items.len;
|
const c = self.kv_temp[0];
|
||||||
|
if (c < '0' or c > '9') {
|
||||||
|
try self.kv.put(alloc, self.kv_current, @intCast(c));
|
||||||
|
self.kv_temp_len = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the value as a string
|
||||||
|
const v = try std.fmt.parseInt(u32, self.kv_temp[0..self.kv_temp_len], 10);
|
||||||
|
try self.kv.put(alloc, self.kv_current, v);
|
||||||
|
|
||||||
|
// Clear our temp buffer
|
||||||
|
self.kv_temp_len = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -247,8 +274,7 @@ pub const Transmission = struct {
|
|||||||
|
|
||||||
fn parse(kv: KV) !Transmission {
|
fn parse(kv: KV) !Transmission {
|
||||||
var result: Transmission = .{};
|
var result: Transmission = .{};
|
||||||
if (kv.get("f")) |str| {
|
if (kv.get('f')) |v| {
|
||||||
const v = try std.fmt.parseInt(u32, str, 10);
|
|
||||||
result.format = switch (v) {
|
result.format = switch (v) {
|
||||||
24 => .rgb,
|
24 => .rgb,
|
||||||
32 => .rgba,
|
32 => .rgba,
|
||||||
@ -257,9 +283,9 @@ pub const Transmission = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("t")) |str| {
|
if (kv.get('t')) |v| {
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
const c = std.math.cast(u8, v) orelse return error.InvalidFormat;
|
||||||
result.medium = switch (str[0]) {
|
result.medium = switch (c) {
|
||||||
'd' => .direct,
|
'd' => .direct,
|
||||||
'f' => .file,
|
'f' => .file,
|
||||||
't' => .temporary_file,
|
't' => .temporary_file,
|
||||||
@ -268,44 +294,43 @@ pub const Transmission = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("s")) |str| {
|
if (kv.get('s')) |v| {
|
||||||
result.width = try std.fmt.parseInt(u32, str, 10);
|
result.width = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("v")) |str| {
|
if (kv.get('v')) |v| {
|
||||||
result.height = try std.fmt.parseInt(u32, str, 10);
|
result.height = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("S")) |str| {
|
if (kv.get('S')) |v| {
|
||||||
result.size = try std.fmt.parseInt(u32, str, 10);
|
result.size = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("O")) |str| {
|
if (kv.get('O')) |v| {
|
||||||
result.offset = try std.fmt.parseInt(u32, str, 10);
|
result.offset = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("i")) |str| {
|
if (kv.get('i')) |v| {
|
||||||
result.image_id = try std.fmt.parseInt(u32, str, 10);
|
result.image_id = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("I")) |str| {
|
if (kv.get('I')) |v| {
|
||||||
result.image_number = try std.fmt.parseInt(u32, str, 10);
|
result.image_number = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("p")) |str| {
|
if (kv.get('p')) |v| {
|
||||||
result.placement_id = try std.fmt.parseInt(u32, str, 10);
|
result.placement_id = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("o")) |str| {
|
if (kv.get('o')) |v| {
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
const c = std.math.cast(u8, v) orelse return error.InvalidFormat;
|
||||||
result.compression = switch (str[0]) {
|
result.compression = switch (c) {
|
||||||
'z' => .zlib_deflate,
|
'z' => .zlib_deflate,
|
||||||
else => return error.InvalidFormat,
|
else => return error.InvalidFormat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("m")) |str| {
|
if (kv.get('m')) |v| {
|
||||||
const v = try std.fmt.parseInt(u32, str, 10);
|
|
||||||
result.more_chunks = v > 0;
|
result.more_chunks = v > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,66 +361,64 @@ pub const Display = struct {
|
|||||||
fn parse(kv: KV) !Display {
|
fn parse(kv: KV) !Display {
|
||||||
var result: Display = .{};
|
var result: Display = .{};
|
||||||
|
|
||||||
if (kv.get("i")) |str| {
|
if (kv.get('i')) |v| {
|
||||||
result.image_id = try std.fmt.parseInt(u32, str, 10);
|
result.image_id = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("I")) |str| {
|
if (kv.get('I')) |v| {
|
||||||
result.image_number = try std.fmt.parseInt(u32, str, 10);
|
result.image_number = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.x = try std.fmt.parseInt(u32, str, 10);
|
result.x = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.y = try std.fmt.parseInt(u32, str, 10);
|
result.y = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("w")) |str| {
|
if (kv.get('w')) |v| {
|
||||||
result.width = try std.fmt.parseInt(u32, str, 10);
|
result.width = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("h")) |str| {
|
if (kv.get('h')) |v| {
|
||||||
result.height = try std.fmt.parseInt(u32, str, 10);
|
result.height = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("X")) |str| {
|
if (kv.get('X')) |v| {
|
||||||
result.x_offset = try std.fmt.parseInt(u32, str, 10);
|
result.x_offset = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("Y")) |str| {
|
if (kv.get('Y')) |v| {
|
||||||
result.y_offset = try std.fmt.parseInt(u32, str, 10);
|
result.y_offset = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("c")) |str| {
|
if (kv.get('c')) |v| {
|
||||||
result.columns = try std.fmt.parseInt(u32, str, 10);
|
result.columns = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("r")) |str| {
|
if (kv.get('r')) |v| {
|
||||||
result.rows = try std.fmt.parseInt(u32, str, 10);
|
result.rows = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("C")) |str| {
|
if (kv.get('C')) |v| {
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
result.cursor_movement = switch (v) {
|
||||||
result.cursor_movement = switch (str[0]) {
|
0 => .after,
|
||||||
'0' => .after,
|
1 => .none,
|
||||||
'1' => .none,
|
|
||||||
else => return error.InvalidFormat,
|
else => return error.InvalidFormat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("U")) |str| {
|
if (kv.get('U')) |v| {
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
result.virtual_placement = switch (v) {
|
||||||
result.virtual_placement = switch (str[0]) {
|
0 => false,
|
||||||
'0' => false,
|
1 => true,
|
||||||
'1' => true,
|
|
||||||
else => return error.InvalidFormat,
|
else => return error.InvalidFormat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("z")) |str| {
|
if (kv.get('z')) |v| {
|
||||||
result.z = try std.fmt.parseInt(u32, str, 10);
|
result.z = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -421,28 +444,27 @@ pub const AnimationFrameLoading = struct {
|
|||||||
fn parse(kv: KV) !AnimationFrameLoading {
|
fn parse(kv: KV) !AnimationFrameLoading {
|
||||||
var result: AnimationFrameLoading = .{};
|
var result: AnimationFrameLoading = .{};
|
||||||
|
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.x = try std.fmt.parseInt(u32, str, 10);
|
result.x = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.y = try std.fmt.parseInt(u32, str, 10);
|
result.y = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("c")) |str| {
|
if (kv.get('c')) |v| {
|
||||||
result.create_frame = try std.fmt.parseInt(u32, str, 10);
|
result.create_frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("r")) |str| {
|
if (kv.get('r')) |v| {
|
||||||
result.edit_frame = try std.fmt.parseInt(u32, str, 10);
|
result.edit_frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("z")) |str| {
|
if (kv.get('z')) |v| {
|
||||||
result.gap_ms = try std.fmt.parseInt(u32, str, 10);
|
result.gap_ms = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("X")) |str| {
|
if (kv.get('X')) |v| {
|
||||||
const v = try std.fmt.parseInt(u32, str, 10);
|
|
||||||
result.composition_mode = switch (v) {
|
result.composition_mode = switch (v) {
|
||||||
0 => .alpha_blend,
|
0 => .alpha_blend,
|
||||||
1 => .overwrite,
|
1 => .overwrite,
|
||||||
@ -450,8 +472,8 @@ pub const AnimationFrameLoading = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("Y")) |str| {
|
if (kv.get('Y')) |v| {
|
||||||
result.background = @bitCast(try std.fmt.parseInt(u32, str, 10));
|
result.background = @bitCast(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -472,40 +494,39 @@ pub const AnimationFrameComposition = struct {
|
|||||||
fn parse(kv: KV) !AnimationFrameComposition {
|
fn parse(kv: KV) !AnimationFrameComposition {
|
||||||
var result: AnimationFrameComposition = .{};
|
var result: AnimationFrameComposition = .{};
|
||||||
|
|
||||||
if (kv.get("c")) |str| {
|
if (kv.get('c')) |v| {
|
||||||
result.frame = try std.fmt.parseInt(u32, str, 10);
|
result.frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("r")) |str| {
|
if (kv.get('r')) |v| {
|
||||||
result.edit_frame = try std.fmt.parseInt(u32, str, 10);
|
result.edit_frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.x = try std.fmt.parseInt(u32, str, 10);
|
result.x = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.y = try std.fmt.parseInt(u32, str, 10);
|
result.y = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("w")) |str| {
|
if (kv.get('w')) |v| {
|
||||||
result.width = try std.fmt.parseInt(u32, str, 10);
|
result.width = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("h")) |str| {
|
if (kv.get('h')) |v| {
|
||||||
result.height = try std.fmt.parseInt(u32, str, 10);
|
result.height = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("X")) |str| {
|
if (kv.get('X')) |v| {
|
||||||
result.left_edge = try std.fmt.parseInt(u32, str, 10);
|
result.left_edge = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("Y")) |str| {
|
if (kv.get('Y')) |v| {
|
||||||
result.top_edge = try std.fmt.parseInt(u32, str, 10);
|
result.top_edge = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("C")) |str| {
|
if (kv.get('C')) |v| {
|
||||||
const v = try std.fmt.parseInt(u32, str, 10);
|
|
||||||
result.composition_mode = switch (v) {
|
result.composition_mode = switch (v) {
|
||||||
0 => .alpha_blend,
|
0 => .alpha_blend,
|
||||||
1 => .overwrite,
|
1 => .overwrite,
|
||||||
@ -534,8 +555,7 @@ pub const AnimationControl = struct {
|
|||||||
fn parse(kv: KV) !AnimationControl {
|
fn parse(kv: KV) !AnimationControl {
|
||||||
var result: AnimationControl = .{};
|
var result: AnimationControl = .{};
|
||||||
|
|
||||||
if (kv.get("s")) |str| {
|
if (kv.get('s')) |v| {
|
||||||
const v = try std.fmt.parseInt(u32, str, 10);
|
|
||||||
result.action = switch (v) {
|
result.action = switch (v) {
|
||||||
0 => .invalid,
|
0 => .invalid,
|
||||||
1 => .stop,
|
1 => .stop,
|
||||||
@ -545,20 +565,20 @@ pub const AnimationControl = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("r")) |str| {
|
if (kv.get('r')) |v| {
|
||||||
result.frame = try std.fmt.parseInt(u32, str, 10);
|
result.frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("z")) |str| {
|
if (kv.get('z')) |v| {
|
||||||
result.gap_ms = try std.fmt.parseInt(u32, str, 10);
|
result.gap_ms = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("c")) |str| {
|
if (kv.get('c')) |v| {
|
||||||
result.current_frame = try std.fmt.parseInt(u32, str, 10);
|
result.current_frame = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kv.get("v")) |str| {
|
if (kv.get('v')) |v| {
|
||||||
result.loops = try std.fmt.parseInt(u32, str, 10);
|
result.loops = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -624,9 +644,9 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
fn parse(kv: KV) !Delete {
|
fn parse(kv: KV) !Delete {
|
||||||
const what: u8 = what: {
|
const what: u8 = what: {
|
||||||
const str = kv.get("d") orelse break :what 'a';
|
const value = kv.get('d') orelse break :what 'a';
|
||||||
if (str.len != 1) return error.InvalidFormat;
|
const c = std.math.cast(u8, value) orelse return error.InvalidFormat;
|
||||||
break :what str[0];
|
break :what c;
|
||||||
};
|
};
|
||||||
|
|
||||||
return switch (what) {
|
return switch (what) {
|
||||||
@ -634,11 +654,11 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'i', 'I' => blk: {
|
'i', 'I' => blk: {
|
||||||
var result: Delete = .{ .id = .{ .delete = what == 'I' } };
|
var result: Delete = .{ .id = .{ .delete = what == 'I' } };
|
||||||
if (kv.get("i")) |str| {
|
if (kv.get('i')) |v| {
|
||||||
result.id.image_id = try std.fmt.parseInt(u32, str, 10);
|
result.id.image_id = v;
|
||||||
}
|
}
|
||||||
if (kv.get("p")) |str| {
|
if (kv.get('p')) |v| {
|
||||||
result.id.placement_id = try std.fmt.parseInt(u32, str, 10);
|
result.id.placement_id = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -646,11 +666,11 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'n', 'N' => blk: {
|
'n', 'N' => blk: {
|
||||||
var result: Delete = .{ .newest = .{ .delete = what == 'N' } };
|
var result: Delete = .{ .newest = .{ .delete = what == 'N' } };
|
||||||
if (kv.get("I")) |str| {
|
if (kv.get('I')) |v| {
|
||||||
result.newest.count = try std.fmt.parseInt(u32, str, 10);
|
result.newest.count = v;
|
||||||
}
|
}
|
||||||
if (kv.get("p")) |str| {
|
if (kv.get('p')) |v| {
|
||||||
result.newest.placement_id = try std.fmt.parseInt(u32, str, 10);
|
result.newest.placement_id = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -662,11 +682,11 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'p', 'P' => blk: {
|
'p', 'P' => blk: {
|
||||||
var result: Delete = .{ .intersect_cell = .{ .delete = what == 'P' } };
|
var result: Delete = .{ .intersect_cell = .{ .delete = what == 'P' } };
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.intersect_cell.x = try std.fmt.parseInt(u32, str, 10);
|
result.intersect_cell.x = v;
|
||||||
}
|
}
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.intersect_cell.y = try std.fmt.parseInt(u32, str, 10);
|
result.intersect_cell.y = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -674,14 +694,14 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'q', 'Q' => blk: {
|
'q', 'Q' => blk: {
|
||||||
var result: Delete = .{ .intersect_cell_z = .{ .delete = what == 'Q' } };
|
var result: Delete = .{ .intersect_cell_z = .{ .delete = what == 'Q' } };
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.intersect_cell_z.x = try std.fmt.parseInt(u32, str, 10);
|
result.intersect_cell_z.x = v;
|
||||||
}
|
}
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.intersect_cell_z.y = try std.fmt.parseInt(u32, str, 10);
|
result.intersect_cell_z.y = v;
|
||||||
}
|
}
|
||||||
if (kv.get("z")) |str| {
|
if (kv.get('z')) |v| {
|
||||||
result.intersect_cell_z.z = try std.fmt.parseInt(u32, str, 10);
|
result.intersect_cell_z.z = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -689,8 +709,8 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'x', 'X' => blk: {
|
'x', 'X' => blk: {
|
||||||
var result: Delete = .{ .column = .{ .delete = what == 'X' } };
|
var result: Delete = .{ .column = .{ .delete = what == 'X' } };
|
||||||
if (kv.get("x")) |str| {
|
if (kv.get('x')) |v| {
|
||||||
result.column.x = try std.fmt.parseInt(u32, str, 10);
|
result.column.x = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -698,8 +718,8 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'y', 'Y' => blk: {
|
'y', 'Y' => blk: {
|
||||||
var result: Delete = .{ .row = .{ .delete = what == 'Y' } };
|
var result: Delete = .{ .row = .{ .delete = what == 'Y' } };
|
||||||
if (kv.get("y")) |str| {
|
if (kv.get('y')) |v| {
|
||||||
result.row.y = try std.fmt.parseInt(u32, str, 10);
|
result.row.y = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
@ -707,8 +727,8 @@ pub const Delete = union(enum) {
|
|||||||
|
|
||||||
'z', 'Z' => blk: {
|
'z', 'Z' => blk: {
|
||||||
var result: Delete = .{ .z = .{ .delete = what == 'Z' } };
|
var result: Delete = .{ .z = .{ .delete = what == 'Z' } };
|
||||||
if (kv.get("z")) |str| {
|
if (kv.get('z')) |v| {
|
||||||
result.z.z = try std.fmt.parseInt(u32, str, 10);
|
result.z.z = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk result;
|
break :blk result;
|
||||||
|
Reference in New Issue
Block a user