Skip to content

Commit

Permalink
Address review
Browse files Browse the repository at this point in the history
  • Loading branch information
jerivas committed Jul 11, 2023
1 parent cd6a2b9 commit ae1c7f3
Showing 1 changed file with 35 additions and 55 deletions.
90 changes: 35 additions & 55 deletions lib/src/value/calculations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,49 @@ export type CalculationValue =

type CalculationValueIterable = CalculationValue[] | List<CalculationValue>;

function checkUnquotedString(value: CalculationValue): void {
function assertUnquotedString(value: unknown): void {
if (value instanceof SassString && value.hasQuotes) {
throw new Error(`Expected ${value} to be an unquoted string.`);
}
if (value instanceof CalculationOperation) {
assertUnquotedString(value.left);
assertUnquotedString(value.right);
}
}

function assertUnquotedStringOrInterpolation(value: unknown): void {
if (
(!(value instanceof SassString) &&
!(value instanceof CalculationInterpolation)) ||
(value instanceof SassString && value.hasQuotes)
) {
throw new Error(
`Expected ${value} to be an unquoted SassString or CalculationInterpolation.`
);
}
}

/* A SassScript calculation */
export class SassCalculation extends Value {
readonly name: string;
readonly arguments: List<CalculationValue>;

private constructor(name: string, args: CalculationValueIterable) {
private constructor(readonly name: string, args: CalculationValueIterable) {
super();
this.name = name;
this.arguments = List(args);
}

static calc(argument: CalculationValue): SassCalculation {
checkUnquotedString(argument);
assertUnquotedString(argument);
return new SassCalculation('calc', [argument]);
}

static min(args: CalculationValueIterable): SassCalculation {
args.forEach(checkUnquotedString);
args.forEach(assertUnquotedString);
return new SassCalculation('min', args);
}

static max(args: CalculationValueIterable): SassCalculation {
args.forEach(checkUnquotedString);
args.forEach(assertUnquotedString);
return new SassCalculation('max', args);
}

Expand All @@ -53,48 +68,24 @@ export class SassCalculation extends Value {
value?: CalculationValue,
max?: CalculationValue
): SassCalculation {
if (value === undefined && max === undefined) {
let minString: string;
if (min instanceof SassString) {
minString = min.text;
} else if (min instanceof CalculationInterpolation) {
minString = min.value;
} else {
throw new Error(
'`value` and `max` are both undefined, but `min` is not a SassString or CalculationInterpolation.'
);
}
const values = minString.split(',').map(s => {
const parsed = parseFloat(s.trim());
return isNaN(parsed) ? undefined : new SassNumber(parsed);
});
const error = new Error(
`Expected \`min\` to be a comma-separated list of numbers, got \`${min}\``
);
if (values[0] === undefined) {
throw error;
} else if (values.length === 2) {
[min, value] = values;
} else if (values.length === 3) {
[min, value, max] = values;
} else {
throw error;
}
} else if (value === undefined && max !== undefined) {
throw new Error('`value` is undefined but `max` is defined.');
if (value === undefined) {
assertUnquotedStringOrInterpolation(min);
} else if (max === undefined) {
assertUnquotedStringOrInterpolation(min);
assertUnquotedStringOrInterpolation(value);
}
const args = [min];
if (value !== undefined) args.push(value);
if (max !== undefined) args.push(max);
args.forEach(checkUnquotedString);
args.forEach(assertUnquotedString);
return new SassCalculation('clamp', args);
}

assertCalculation(): SassCalculation {
return this;
}

equals(other: Value): boolean {
equals(other: unknown): boolean {
return (
other instanceof SassCalculation &&
this.name === other.name &&
Expand All @@ -115,24 +106,17 @@ const operators = ['+', '-', '*', '/'] as const;
export type CalculationOperator = typeof operators[number];

export class CalculationOperation implements ValueObject {
readonly operator: CalculationOperator;
readonly left: CalculationValue;
readonly right: CalculationValue;

constructor(
operator: CalculationOperator,
left: CalculationValue,
right: CalculationValue
readonly operator: CalculationOperator,
readonly left: CalculationValue,
readonly right: CalculationValue
) {
if (!operators.includes(operator)) {
throw new Error(`Unknown operator ${operator}`);
}
this.operator = operator;
this.left = left;
this.right = right;
}

equals(other: Value): boolean {
equals(other: unknown): boolean {
return (
other instanceof CalculationOperation &&
this.operator === other.operator &&
Expand All @@ -147,13 +131,9 @@ export class CalculationOperation implements ValueObject {
}

export class CalculationInterpolation implements ValueObject {
readonly value: string;

constructor(value: string) {
this.value = value;
}
constructor(readonly value: string) {}

equals(other: Value): boolean {
equals(other: unknown): boolean {
return (
other instanceof CalculationInterpolation && this.value === other.value
);
Expand Down

0 comments on commit ae1c7f3

Please sign in to comment.