double.ts 2.0 KB

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