aboutsummaryrefslogtreecommitdiff
path: root/ts/device/object_set.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ts/device/object_set.ts')
-rw-r--r--ts/device/object_set.ts85
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);
+}