-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ardupilot.ts: deal with setting non-flat data
- Loading branch information
1 parent
ec1c98f
commit c6e5965
Showing
3 changed files
with
125 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/** | ||
* Result of flattening a data structure | ||
*/ | ||
export type FlattenedPair = { | ||
/** | ||
* | ||
*/ | ||
path: string | ||
/** | ||
* | ||
*/ | ||
value: string | number | boolean | ||
/** | ||
* | ||
*/ | ||
type: 'string' | 'number' | 'boolean' | ||
} | ||
|
||
/** | ||
* Type guard to check if a value is an array of numbers | ||
* @param {unknown[]} data The data to check | ||
* @returns {data is number[]} True if the array contains numbers | ||
*/ | ||
function isNumberArray(data: unknown[]): data is number[] { | ||
return typeof data[0] === 'number' | ||
} | ||
|
||
/** | ||
* Type guard to check if a value is an array of strings | ||
* @param {unknown[]} data The data to check | ||
* @returns {data is string[]} True if the array contains strings | ||
*/ | ||
function isStringArray(data: unknown[]): data is string[] { | ||
return typeof data[0] === 'string' | ||
} | ||
|
||
/** | ||
* Flattens complex data structures into simple types that can be stored in the data lake | ||
* @param {Record<string, unknown>} data The data to flatten | ||
* @returns {FlattenedPair[]} Array of flattened path/value pairs | ||
*/ | ||
export function flattenData(data: Record<string, unknown>): FlattenedPair[] { | ||
if (!('type' in data)) return [] | ||
const messageName = data.type as string | ||
|
||
// Special handling for NAMED_VALUE_FLOAT messages | ||
if (messageName === 'NAMED_VALUE_FLOAT') { | ||
const name = (data.name as string[]).join('').replace(/\0/g, '') | ||
return [ | ||
{ | ||
path: `${messageName}/${name}`, | ||
type: 'number', | ||
value: data.value as number, | ||
}, | ||
...Object.entries(data) | ||
.filter(([key]) => !['name', 'value', 'type'].includes(key)) | ||
.map(([key, value]) => ({ | ||
path: `${messageName}/${key}`, | ||
type: typeof value as 'string' | 'number' | 'boolean', | ||
value: value as string | number | boolean, | ||
})), | ||
] | ||
} | ||
|
||
// For all other messages | ||
return Object.entries(data) | ||
.filter(([key]) => key !== 'type') | ||
.flatMap(([key, value]) => { | ||
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { | ||
return [ | ||
{ | ||
path: `${messageName}/${key}`, | ||
type: typeof value as 'string' | 'number' | 'boolean', | ||
value, | ||
}, | ||
] | ||
} | ||
if (Array.isArray(value)) { | ||
if (value.length === 0) return [] | ||
if (isNumberArray(value)) { | ||
return value.map((item, index) => ({ | ||
path: `${messageName}/${key}/${index}`, | ||
type: 'number', | ||
value: item, | ||
})) | ||
} | ||
if (isStringArray(value)) { | ||
return [ | ||
{ | ||
path: `${messageName}/${key}`, | ||
type: 'string', | ||
value: value.join(''), | ||
}, | ||
] | ||
} | ||
} | ||
return [] | ||
}) | ||
} |