double.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { BSONValue } from './bson_value';
  2. import type { EJSONOptions } from './extended_json';
  3. import { type InspectFn, defaultInspect } from './parser/utils';
  4. /** @public */
  5. export interface DoubleExtended {
  6. $numberDouble: string;
  7. }
  8. /**
  9. * A class representation of the BSON Double type.
  10. * @public
  11. * @category BSONType
  12. */
  13. export class Double extends BSONValue {
  14. get _bsontype(): 'Double' {
  15. return 'Double';
  16. }
  17. value!: number;
  18. /**
  19. * Create a Double type
  20. *
  21. * @param value - the number we want to represent as a double.
  22. */
  23. constructor(value: number) {
  24. super();
  25. if ((value as unknown) instanceof Number) {
  26. value = value.valueOf();
  27. }
  28. this.value = +value;
  29. }
  30. /**
  31. * Access the number value.
  32. *
  33. * @returns returns the wrapped double number.
  34. */
  35. valueOf(): number {
  36. return this.value;
  37. }
  38. toJSON(): number {
  39. return this.value;
  40. }
  41. toString(radix?: number): string {
  42. return this.value.toString(radix);
  43. }
  44. /** @internal */
  45. toExtendedJSON(options?: EJSONOptions): number | DoubleExtended {
  46. if (options && (options.legacy || (options.relaxed && isFinite(this.value)))) {
  47. return this.value;
  48. }
  49. if (Object.is(Math.sign(this.value), -0)) {
  50. // NOTE: JavaScript has +0 and -0, apparently to model limit calculations. If a user
  51. // explicitly provided `-0` then we need to ensure the sign makes it into the output
  52. return { $numberDouble: '-0.0' };
  53. }
  54. return {
  55. $numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString()
  56. };
  57. }
  58. /** @internal */
  59. static fromExtendedJSON(doc: DoubleExtended, options?: EJSONOptions): number | Double {
  60. const doubleValue = parseFloat(doc.$numberDouble);
  61. return options && options.relaxed ? doubleValue : new Double(doubleValue);
  62. }
  63. inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
  64. inspect ??= defaultInspect;
  65. return `new Double(${inspect(this.value, options)})`;
  66. }
  67. }