mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
76 lines
2.6 KiB
Zig
76 lines
2.6 KiB
Zig
const std = @import("std");
|
|
const bun = @import("bun");
|
|
pub const css = @import("../css_parser.zig");
|
|
const Result = css.Result;
|
|
const Printer = css.Printer;
|
|
const PrintErr = css.PrintErr;
|
|
const CSSNumberFns = css.css_values.number.CSSNumberFns;
|
|
const LengthPercentage = css.css_values.length.LengthPercentage;
|
|
|
|
/// A generic value that represents a value with two components, e.g. a border radius.
|
|
///
|
|
/// When serialized, only a single component will be written if both are equal.
|
|
pub fn Size2D(comptime T: type) type {
|
|
return struct {
|
|
a: T,
|
|
b: T,
|
|
|
|
fn parseVal(input: *css.Parser) Result(T) {
|
|
return switch (T) {
|
|
f32 => return CSSNumberFns.parse(input),
|
|
LengthPercentage => return LengthPercentage.parse(input),
|
|
else => T.parse(input),
|
|
};
|
|
}
|
|
|
|
pub fn parse(input: *css.Parser) Result(Size2D(T)) {
|
|
const first = switch (parseVal(input)) {
|
|
.result => |vv| vv,
|
|
.err => |e| return .{ .err = e },
|
|
};
|
|
const second = input.tryParse(parseVal, .{}).unwrapOr(first);
|
|
return .{ .result = Size2D(T){
|
|
.a = first,
|
|
.b = second,
|
|
} };
|
|
}
|
|
|
|
pub fn toCss(this: *const Size2D(T), comptime W: type, dest: *css.Printer(W)) css.PrintErr!void {
|
|
try valToCss(&this.a, W, dest);
|
|
if (!valEql(&this.b, &this.a)) {
|
|
try dest.writeStr(" ");
|
|
try valToCss(&this.b, W, dest);
|
|
}
|
|
}
|
|
|
|
pub fn valToCss(val: *const T, comptime W: type, dest: *css.Printer(W)) css.PrintErr!void {
|
|
return switch (T) {
|
|
f32 => CSSNumberFns.toCss(val, W, dest),
|
|
else => val.toCss(W, dest),
|
|
};
|
|
}
|
|
|
|
pub fn isCompatible(this: *const @This(), browsers: bun.css.targets.Browsers) bool {
|
|
return this.a.isCompatible(browsers) and this.b.isCompatible(browsers);
|
|
}
|
|
|
|
pub fn deepClone(this: *const @This(), allocator: std.mem.Allocator) @This() {
|
|
return css.implementDeepClone(@This(), this, allocator);
|
|
}
|
|
|
|
pub inline fn valEql(lhs: *const T, rhs: *const T) bool {
|
|
return switch (T) {
|
|
f32 => lhs.* == rhs.*,
|
|
else => lhs.eql(rhs),
|
|
};
|
|
}
|
|
|
|
pub inline fn eql(lhs: *const @This(), rhs: *const @This()) bool {
|
|
return switch (T) {
|
|
f32 => lhs.a == rhs.b,
|
|
else => lhs.a.eql(&rhs.b),
|
|
};
|
|
}
|
|
};
|
|
}
|