mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
No longer needed after zig upgrade --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
216 lines
7.8 KiB
Zig
216 lines
7.8 KiB
Zig
pub const css = @import("../css_parser.zig");
|
|
const Result = css.Result;
|
|
const Printer = css.Printer;
|
|
const PrintErr = css.PrintErr;
|
|
const CSSNumber = css.css_values.number.CSSNumber;
|
|
const CSSNumberFns = css.css_values.number.CSSNumberFns;
|
|
const Calc = css.css_values.calc.Calc;
|
|
const Angle = css.css_values.angle.Angle;
|
|
|
|
/// A CSS [`<time>`](https://www.w3.org/TR/css-values-4/#time) value, in either
|
|
/// seconds or milliseconds.
|
|
///
|
|
/// Time values may be explicit or computed by `calc()`, but are always stored and serialized
|
|
/// as their computed value.
|
|
pub const Time = union(Tag) {
|
|
/// A time in seconds.
|
|
seconds: CSSNumber,
|
|
/// A time in milliseconds.
|
|
milliseconds: CSSNumber,
|
|
|
|
const Tag = enum(u8) { seconds = 1, milliseconds = 2 };
|
|
|
|
pub fn deepClone(this: *const @This(), allocator: std.mem.Allocator) @This() {
|
|
return css.implementDeepClone(@This(), this, allocator);
|
|
}
|
|
|
|
pub fn eql(lhs: *const @This(), rhs: *const @This()) bool {
|
|
return css.implementEql(@This(), lhs, rhs);
|
|
}
|
|
pub fn hash(this: *const @This(), hasher: *std.hash.Wyhash) void {
|
|
return css.implementHash(@This(), this, hasher);
|
|
}
|
|
|
|
pub fn parse(input: *css.Parser) Result(Time) {
|
|
switch (input.tryParse(Calc(Time).parse, .{})) {
|
|
.result => |vv| switch (vv) {
|
|
.value => |v| {
|
|
const ret: Time = v.*;
|
|
// redundant allocation
|
|
var vvv = vv;
|
|
vvv.deinit(input.allocator());
|
|
return .{ .result = ret };
|
|
},
|
|
// Time is always compatible, so they will always compute to a value.
|
|
else => return .{ .err = input.newErrorForNextToken() },
|
|
},
|
|
.err => {},
|
|
}
|
|
|
|
const location = input.currentSourceLocation();
|
|
const token = switch (input.next()) {
|
|
.result => |vv| vv,
|
|
.err => |e| return .{ .err = e },
|
|
};
|
|
switch (token.*) {
|
|
.dimension => |*dim| {
|
|
if (bun.strings.eqlCaseInsensitiveASCIIICheckLength("s", dim.unit)) {
|
|
return .{ .result = .{ .seconds = dim.num.value } };
|
|
} else if (bun.strings.eqlCaseInsensitiveASCIIICheckLength("ms", dim.unit)) {
|
|
return .{ .result = .{ .milliseconds = dim.num.value } };
|
|
} else {
|
|
return .{ .err = location.newUnexpectedTokenError(css.Token{ .ident = dim.unit }) };
|
|
}
|
|
},
|
|
else => return .{ .err = location.newUnexpectedTokenError(token.*) },
|
|
}
|
|
}
|
|
|
|
pub fn toCss(this: *const @This(), dest: *css.Printer) css.PrintErr!void {
|
|
// 0.1s is shorter than 100ms
|
|
// anything smaller is longer
|
|
switch (this.*) {
|
|
.seconds => |s| {
|
|
if (s > 0.0 and s < 0.1) {
|
|
try CSSNumberFns.toCss(&(s * 1000.0), dest);
|
|
try dest.writeStr("ms");
|
|
} else {
|
|
try CSSNumberFns.toCss(&s, dest);
|
|
try dest.writeStr("s");
|
|
}
|
|
},
|
|
.milliseconds => |ms| {
|
|
if (ms == 0.0 or ms >= 100.0) {
|
|
try CSSNumberFns.toCss(&(ms / 1000.0), dest);
|
|
try dest.writeStr("s");
|
|
} else {
|
|
try CSSNumberFns.toCss(&ms, dest);
|
|
try dest.writeStr("ms");
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn isZero(this: *const Time) bool {
|
|
return switch (this.*) {
|
|
.seconds => |s| s == 0.0,
|
|
.milliseconds => |ms| ms == 0.0,
|
|
};
|
|
}
|
|
|
|
/// Returns the time in milliseconds.
|
|
pub fn toMs(this: *const Time) CSSNumber {
|
|
return switch (this.*) {
|
|
.seconds => |v| v * 1000.0,
|
|
.milliseconds => |v| v,
|
|
};
|
|
}
|
|
|
|
pub fn tryFromToken(token: *const css.Token) css.Maybe(Time, void) {
|
|
switch (token.*) {
|
|
.dimension => |*dim| {
|
|
// todo_stuff.match_ignore_ascii_case
|
|
if (bun.strings.eqlCaseInsensitiveASCIIICheckLength("s", dim.unit)) {
|
|
return .{ .result = .{ .seconds = dim.num.value } };
|
|
} else if (bun.strings.eqlCaseInsensitiveASCIIICheckLength("ms", dim.unit)) {
|
|
return .{ .result = .{ .milliseconds = dim.num.value } };
|
|
}
|
|
},
|
|
else => {},
|
|
}
|
|
|
|
return .{ .err = {} };
|
|
}
|
|
|
|
pub fn tryFromAngle(_: css.css_values.angle.Angle) ?@This() {
|
|
return null;
|
|
}
|
|
|
|
pub fn mulF32(this: @This(), _: std.mem.Allocator, other: f32) Time {
|
|
return switch (this) {
|
|
.seconds => .{ .seconds = this.seconds * other },
|
|
.milliseconds => .{ .milliseconds = this.milliseconds * other },
|
|
};
|
|
}
|
|
|
|
pub fn addInternal(this: Time, allocator: std.mem.Allocator, other: Time) Time {
|
|
return this.add(allocator, other);
|
|
}
|
|
|
|
pub fn intoCalc(this: Time, allocator: std.mem.Allocator) Calc(Time) {
|
|
return Calc(Time){ .value = bun.create(allocator, Time, this) };
|
|
}
|
|
|
|
pub fn add(this: @This(), _: std.mem.Allocator, other: @This()) Time {
|
|
return this.op(&other, {}, struct {
|
|
fn mul(_: void, a: f32, b: f32) f32 {
|
|
return a + b;
|
|
}
|
|
}.mul);
|
|
}
|
|
|
|
pub fn partialCmp(this: *const Time, other: *const Time) ?std.math.Order {
|
|
return css.generic.partialCmpF32(&this.toMs(), &other.toMs());
|
|
}
|
|
|
|
pub fn map(this: *const @This(), comptime map_fn: *const fn (f32) f32) Time {
|
|
return switch (this.*) {
|
|
.seconds => Time{ .seconds = map_fn(this.seconds) },
|
|
.milliseconds => Time{ .milliseconds = map_fn(this.milliseconds) },
|
|
};
|
|
}
|
|
|
|
pub fn sign(this: *const Time) f32 {
|
|
return switch (this.*) {
|
|
.seconds => |v| CSSNumberFns.sign(&v),
|
|
.milliseconds => |v| CSSNumberFns.sign(&v),
|
|
};
|
|
}
|
|
|
|
pub fn op(
|
|
this: *const Time,
|
|
other: *const Time,
|
|
ctx: anytype,
|
|
comptime op_fn: *const fn (@TypeOf(ctx), a: f32, b: f32) f32,
|
|
) Time {
|
|
const self_tag: u16 = @intFromEnum(this.*);
|
|
const other_tag: u16 = @intFromEnum(other.*);
|
|
const S: u16 = @intFromEnum(Tag.seconds);
|
|
const MS: u16 = @intFromEnum(Tag.milliseconds);
|
|
|
|
const switch_val: u16 = self_tag | (@as(u16, other_tag) << 8);
|
|
return switch (switch_val) {
|
|
S | (S << 8) => Time{ .seconds = op_fn(ctx, this.seconds, other.seconds) },
|
|
MS | (MS << 8) => Time{ .milliseconds = op_fn(ctx, this.milliseconds, other.milliseconds) },
|
|
S | (MS << 8) => Time{ .seconds = op_fn(ctx, this.seconds, other.milliseconds / 1000.0) },
|
|
MS | (S << 8) => Time{ .milliseconds = op_fn(ctx, this.milliseconds, other.seconds * 1000.0) },
|
|
else => unreachable,
|
|
};
|
|
}
|
|
|
|
pub fn opTo(
|
|
this: *const Time,
|
|
other: *const Time,
|
|
comptime R: type,
|
|
ctx: anytype,
|
|
comptime op_fn: *const fn (@TypeOf(ctx), a: f32, b: f32) R,
|
|
) R {
|
|
const self_tag: u16 = @intFromEnum(this.*);
|
|
const other_tag: u16 = @intFromEnum(other.*);
|
|
const S: u16 = @intFromEnum(Tag.seconds);
|
|
const MS: u16 = @intFromEnum(Tag.milliseconds);
|
|
|
|
const switch_val: u16 = self_tag | (@as(u16, other_tag) << 8);
|
|
return switch (switch_val) {
|
|
S | (S << 8) => op_fn(ctx, this.seconds, other.seconds),
|
|
MS | (MS << 8) => op_fn(ctx, this.milliseconds, other.milliseconds),
|
|
S | (MS << 8) => op_fn(ctx, this.seconds, other.milliseconds / 1000.0),
|
|
MS | (S << 8) => op_fn(ctx, this.milliseconds, other.seconds * 1000.0),
|
|
else => unreachable,
|
|
};
|
|
}
|
|
};
|
|
|
|
const bun = @import("bun");
|
|
const std = @import("std");
|