1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3'use strict';
4
5import {
6  IDiffModel
7} from './common';
8
9import {
10  IDiffImmutableObjectEntry
11} from '../diffentries';
12
13
14
15export type ImmutableValue = number | boolean | null;
16
17
18/**
19 * Standard implementation of the IStringDiffModel interface.
20 */
21export
22class ImmutableDiffModel implements IDiffModel {
23
24  /**
25   * ImmutableDiffModel constructor.
26   *
27   * `collapsible` and `collapsed` both defaults to false.
28   */
29  constructor(
30        base: ImmutableValue | undefined,
31        remote: ImmutableValue | undefined,
32        collapsible?: boolean,
33        header?: string,
34        collapsed?: boolean) {
35    this.base = base;
36    this.remote = remote;
37
38    this.collapsible = collapsible === true;
39    if (this.collapsible) {
40      this.collapsibleHeader = header ? header : '';
41      this.startCollapsed = collapsed === true;
42    }
43  }
44
45  get unchanged(): boolean {
46    return this.base === this.remote;
47  }
48
49  get added(): boolean {
50    return this.base === undefined;
51  }
52
53  get deleted(): boolean {
54    return this.remote === undefined;
55  }
56
57  base: ImmutableValue | undefined;
58  remote: ImmutableValue | undefined;
59
60  collapsible: boolean;
61  collapsibleHeader: string;
62  startCollapsed: boolean;
63}
64
65
66/**
67 * Create an ImmutableDiffModel from a base value, a remote value, and a single diff entry.
68 *
69 * Note: The requirement of a single diff entry means it will not support
70 * an add/replace pair on the same key, as this should instead be represented
71 * by a 'replace' op.
72 *
73 * @export
74 * @param {(ImmutableValue | undefined)} base : The base value
75 * @param {(IDiffImmutableObjectEntry | null)} diff : The diff entry, or null if unchanged
76 * @returns {ImmutableDiffModel}
77 */
78export
79function createImmutableModel(base: ImmutableValue | undefined, remote: ImmutableValue | undefined, diff?: IDiffImmutableObjectEntry | null): ImmutableDiffModel {
80  if (!diff) {
81    return new ImmutableDiffModel(base, remote);
82  } else if (diff.op === 'add') {
83    if (base !== undefined) {
84      throw new Error('Invalid diff op on immutable value');
85    }
86    return new ImmutableDiffModel(base, diff.value);
87  } else if (diff.op === 'remove') {
88    if (base === undefined) {
89      throw new Error('Invalid diff op on immutable value');
90    }
91    return new ImmutableDiffModel(base, undefined);
92  } else { // diff.op === 'replace'
93    if (base === undefined) {
94      throw new Error('Invalid diff op on immutable value');
95    }
96    return new ImmutableDiffModel(base, diff.value);
97  }
98}
99