diff options
Diffstat (limited to 'ts/device/object_set.ts')
-rw-r--r-- | ts/device/object_set.ts | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/ts/device/object_set.ts b/ts/device/object_set.ts new file mode 100644 index 000000000..7bc5f1d91 --- /dev/null +++ b/ts/device/object_set.ts @@ -0,0 +1,85 @@ +// Copyright 2023 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +type ObjectType = { + [index: number | string]: any; +}; + +function hasOwnProperty(obj: ObjectType, prop: number | string) { + if (obj == null) { + return false; + } + //to handle objects with null prototypes (too edge case?) + return Object.prototype.hasOwnProperty.call(obj, prop); +} +function hasShallowProperty(obj: ObjectType, prop: number | string) { + return ( + (typeof prop === 'number' && Array.isArray(obj)) || + hasOwnProperty(obj, prop) + ); +} + +function getShallowProperty(obj: ObjectType, prop: number | string) { + if (hasShallowProperty(obj, prop)) { + return obj[prop]; + } +} +function getKey(key: string) { + const intKey = parseInt(key); + if (intKey.toString() === key) { + return intKey; + } + return key; +} + +export function setPathOnObject( + obj: ObjectType, + path: number | string | Array<number | string>, + value: any, + doNotReplace: boolean = false, +) { + if (typeof path === 'number') { + path = [path]; + } + if (!path || path.length === 0) { + return obj; + } + if (typeof path === 'string') { + return setPathOnObject( + obj, + path.split('.').map(getKey), + value, + doNotReplace, + ); + } + const currentPath = path[0]; + const currentValue = getShallowProperty(obj, currentPath); + if (path.length === 1) { + if (currentValue === void 0 || !doNotReplace) { + obj[currentPath] = value; + } + return currentValue; + } + + if (currentValue === void 0) { + //check if we assume an array + if (typeof path[1] === 'number') { + obj[currentPath] = []; + } else { + obj[currentPath] = {}; + } + } + + return setPathOnObject(obj[currentPath], path.slice(1), value, doNotReplace); +} |