Compare commits

...

4 Commits

Author SHA1 Message Date
33822b5a19 Bump to v0.6.1 (#465) 2023-09-13 06:33:11 -04:00
a2a4daebe3 fix move cmd order (#462) 2023-09-13 07:42:42 +00:00
a17ede50bd Build endpoint for download page on website (#451) 2023-09-13 03:03:13 +00:00
2d452f80d1 ts-rs changes (#450)
* initial changes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* bust cache

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add dumb shit

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* Revert "add dumb shit"

This reverts commit 638e9cf72f75e1ad08fb6b22d2a7b143ab7e06e5.

* Revert "bust cache"

This reverts commit fd6f53ba0757d635190aa82d4b055a83755f3027.

* fix

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2023-09-13 11:10:27 +10:00
21 changed files with 172 additions and 180 deletions

View File

@ -1,6 +1,6 @@
VITE_KC_API_WS_MODELING_URL=wss://api.dev.kittycad.io/ws/modeling/commands
VITE_KC_API_BASE_URL=https://api.dev.kittycad.io
VITE_KC_SITE_BASE_URL=https://dev.kittycad.io
VITE_KC_API_WS_MODELING_URL=wss://api.kittycad.io/ws/modeling/commands
VITE_KC_API_BASE_URL=https://api.kittycad.io
VITE_KC_SITE_BASE_URL=https://kittycad.io
VITE_KC_SKIP_AUTH=false
VITE_KC_CONNECTION_TIMEOUT_MS=5000
VITE_KC_CONNECTION_TIMEOUT_MS=15000
VITE_KC_SENTRY_DSN=

View File

@ -153,6 +153,8 @@ jobs:
needs: [build-test-web, build-apps]
env:
VERSION_NO_V: ${{ needs.build-test-web.outputs.version }}
PUB_DATE: ${{ github.event.release.created_at }}
NOTES: ${{ github.event.release.body }}
steps:
- uses: actions/download-artifact@v3
@ -166,6 +168,8 @@ jobs:
RELEASE_DIR=https://dl.kittycad.io/releases/modeling-app/v${VERSION_NO_V}
jq --null-input \
--arg version "v${VERSION_NO_V}" \
--arg pub_date "${PUB_DATE}" \
--arg notes "${NOTES}" \
--arg darwin_sig "$DARWIN_SIG" \
--arg darwin_url "$RELEASE_DIR/macos/KittyCAD%20Modeling.app.tar.gz" \
--arg linux_sig "$LINUX_SIG" \
@ -174,6 +178,8 @@ jobs:
--arg windows_url "$RELEASE_DIR/nsis/KittyCAD%20Modeling_${VERSION_NO_V}_x64-setup.nsis.zip" \
'{
"version": $version,
"pub_date": $pub_date,
"notes": $notes,
"platforms": {
"darwin-x86_64": {
"signature": $darwin_sig,
@ -195,6 +201,34 @@ jobs:
}' > last_update.json
cat last_update.json
- name: Generate the download static endpoint
run: |
RELEASE_DIR=https://dl.kittycad.io/releases/modeling-app/v${VERSION_NO_V}
jq --null-input \
--arg version "v${VERSION_NO_V}" \
--arg pub_date "${PUB_DATE}" \
--arg notes "${NOTES}" \
--arg darwin_url "$RELEASE_DIR/dmg/KittyCAD%20Modeling_${VERSION_NO_V}_universal.dmg" \
--arg linux_url "$RELEASE_DIR/appimage/kittycad-modeling_${VERSION_NO_V}_amd64.AppImage" \
--arg windows_url "$RELEASE_DIR/msi/KittyCAD%20Modeling_${VERSION_NO_V}_x64_en-US.msi.zip" \
'{
"version": $version,
"pub_date": $pub_date,
"notes": $notes,
"platforms": {
"dmg-universal": {
"url": $darwin_url
},
"appimage-x86_64": {
"url": $linux_url
},
"msi-x86_64": {
"url": $windows_url
}
}
}' > last_download.json
cat last_download.json
- name: Authenticate to Google Cloud
uses: 'google-github-actions/auth@v1.1.1'
with:
@ -219,6 +253,12 @@ jobs:
path: last_update.json
destination: dl.kittycad.io/releases/modeling-app
- name: Upload download endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v1.0.3
with:
path: last_download.json
destination: dl.kittycad.io/releases/modeling-app
- name: Upload release files to Github
uses: softprops/action-gh-release@v1
with:

View File

@ -1,6 +1,6 @@
{
"name": "untitled-app",
"version": "0.6.0",
"version": "0.6.1",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.9.0",

View File

@ -8,7 +8,7 @@
},
"package": {
"productName": "kittycad-modeling",
"version": "0.6.0"
"version": "0.6.1"
},
"tauri": {
"allowlist": {

View File

@ -192,7 +192,7 @@ export function App() {
start: null,
},
})
setProgramMemory({ root: {} })
setProgramMemory({ root: {}, return: null })
engineCommandManager.endSession()
engineCommandManager.startNewSession()
return
@ -209,26 +209,27 @@ export function App() {
{
root: {
_0: {
type: 'userVal',
type: 'UserVal',
value: 0,
__meta: [],
},
_90: {
type: 'userVal',
type: 'UserVal',
value: 90,
__meta: [],
},
_180: {
type: 'userVal',
type: 'UserVal',
value: 180,
__meta: [],
},
_270: {
type: 'userVal',
type: 'UserVal',
value: 270,
__meta: [],
},
},
return: null,
},
engineCommandManager
)
@ -313,18 +314,6 @@ export function App() {
window: { x, y },
},
})
} else if (
guiMode.mode === 'sketch' &&
guiMode.sketchMode === ('move' as any)
) {
debounceSocketSend({
type: 'modeling_cmd_req',
cmd_id: newCmdId,
cmd: {
type: 'handle_mouse_drag_move',
window: { x, y },
},
})
} else {
debounceSocketSend({
type: 'modeling_cmd_req',
@ -336,6 +325,17 @@ export function App() {
})
}
} else {
if (guiMode.mode === 'sketch' && guiMode.sketchMode === ('move' as any)) {
debounceSocketSend({
type: 'modeling_cmd_req',
cmd_id: newCmdId,
cmd: {
type: 'handle_mouse_drag_move',
window: { x, y },
},
})
return
}
const interactionGuards = cameraMouseDragGuards[cameraControls]
let interaction: CameraDragInteractionType_type

View File

@ -144,7 +144,7 @@ export function useCalc({
try {
const code = `const __result__ = ${value}\nshow(__result__)`
const ast = parser_wasm(code)
const _programMem: any = { root: {} }
const _programMem: any = { root: {}, return: null }
availableVarInfo.variables.forEach(({ key, value }) => {
_programMem.root[key] = { type: 'userVal', value, __meta: [] }
})

View File

@ -29,6 +29,7 @@ describe('processMemory', () => {
const ast = parser_wasm(code)
const programMemory = await enginelessExecutor(ast, {
root: {},
return: null,
})
const output = processMemory(programMemory)
expect(output.myVar).toEqual(5)

View File

@ -2,7 +2,7 @@ import ReactJson from 'react-json-view'
import { CollapsiblePanel, CollapsiblePanelProps } from './CollapsiblePanel'
import { useStore } from '../useStore'
import { useMemo } from 'react'
import { ProgramMemory } from '../lang/executor'
import { ProgramMemory, Path, ExtrudeSurface } from '../lang/executor'
import { Themes } from '../lib/theme'
interface MemoryPanelProps extends CollapsiblePanelProps {
@ -49,8 +49,12 @@ export const processMemory = (programMemory: ProgramMemory) => {
Object.keys(programMemory.root).forEach((key) => {
const val = programMemory.root[key]
if (typeof val.value !== 'function') {
if (val.type === 'sketchGroup' || val.type === 'extrudeGroup') {
processedMemory[key] = val.value.map(({ __geoMeta, ...rest }) => {
if (val.type === 'SketchGroup') {
processedMemory[key] = val.value.map(({ __geoMeta, ...rest }: Path) => {
return rest
})
} else if (val.type === 'ExtrudeGroup') {
processedMemory[key] = val.value.map(({ ...rest }: ExtrudeSurface) => {
return rest
})
} else {

View File

@ -21,7 +21,7 @@ show(mySketch001)`
)
expect(shown).toEqual([
{
type: 'sketchGroup',
type: 'SketchGroup',
start: {
to: [0, 0],
from: [0, 0],
@ -77,7 +77,7 @@ show(mySketch001)`
)
expect(shown).toEqual([
{
type: 'extrudeGroup',
type: 'ExtrudeGroup',
id: expect.any(String),
value: [],
height: 2,
@ -117,7 +117,7 @@ show(theExtrude, sk2)`
)
expect(geos).toEqual([
{
type: 'extrudeGroup',
type: 'ExtrudeGroup',
id: expect.any(String),
value: [],
height: 2,
@ -126,7 +126,7 @@ show(theExtrude, sk2)`
__meta: [{ sourceRange: [13, 34] }],
},
{
type: 'extrudeGroup',
type: 'ExtrudeGroup',
id: expect.any(String),
value: [],
height: 2,

View File

@ -1,7 +1,7 @@
import fs from 'node:fs'
import { parser_wasm } from './abstractSyntaxTree'
import { ProgramMemory } from './executor'
import { ProgramMemory, SketchGroup } from './executor'
import { initPromise } from './rust'
import { enginelessExecutor } from '../lib/testHelpers'
import { vi } from 'vitest'
@ -117,10 +117,10 @@ show(mySketch)
// ].join('\n')
// const { root } = await exe(code)
// expect(root.mySk1.value).toHaveLength(3)
// expect(root?.rotated?.type).toBe('sketchGroup')
// expect(root?.rotated?.type).toBe('SketchGroup')
// if (
// root?.mySk1?.type !== 'sketchGroup' ||
// root?.rotated?.type !== 'sketchGroup'
// root?.mySk1?.type !== 'SketchGroup' ||
// root?.rotated?.type !== 'SketchGroup'
// )
// throw new Error('not a sketch group')
// expect(root.mySk1.rotation).toEqual([0, 0, 0, 1])
@ -143,7 +143,7 @@ show(mySketch)
].join('\n')
const { root } = await exe(code)
expect(root.mySk1).toEqual({
type: 'sketchGroup',
type: 'SketchGroup',
start: {
to: [0, 0],
from: [0, 0],
@ -199,7 +199,7 @@ show(mySketch)
// TODO path to node is probably wrong here, zero indexes are not correct
expect(root).toEqual({
three: {
type: 'userVal',
type: 'UserVal',
value: 3,
__meta: [
{
@ -208,7 +208,7 @@ show(mySketch)
],
},
yo: {
type: 'userVal',
type: 'UserVal',
value: [1, '2', 3, 9],
__meta: [
{
@ -225,7 +225,7 @@ show(mySketch)
].join('\n')
const { root } = await exe(code)
expect(root.yo).toEqual({
type: 'userVal',
type: 'UserVal',
value: { aStr: 'str', anum: 2, identifier: 3, binExp: 9 },
__meta: [
{
@ -240,7 +240,7 @@ show(mySketch)
)
const { root } = await exe(code)
expect(root.myVar).toEqual({
type: 'userVal',
type: 'UserVal',
value: '123',
__meta: [
{
@ -338,7 +338,7 @@ describe('testing math operators', () => {
const { root } = await exe(code)
const sketch = root.part001
// result of `-legLen(5, min(3, 999))` should be -4
const yVal = sketch.value?.[0]?.to?.[1]
const yVal = (sketch as SketchGroup).value?.[0]?.to?.[1]
expect(yVal).toBe(-4)
})
it('test that % substitution feeds down CallExp->ArrExp->UnaryExp->CallExp', async () => {
@ -356,8 +356,8 @@ describe('testing math operators', () => {
const { root } = await exe(code)
const sketch = root.part001
// expect -legLen(segLen('seg01', %), myVar) to equal -4 setting the y value back to 0
expect(sketch.value?.[1]?.from).toEqual([3, 4])
expect(sketch.value?.[1]?.to).toEqual([6, 0])
expect((sketch as SketchGroup).value?.[1]?.from).toEqual([3, 4])
expect((sketch as SketchGroup).value?.[1]?.to).toEqual([6, 0])
const removedUnaryExp = code.replace(
`-legLen(segLen('seg01', %), myVar)`,
`legLen(segLen('seg01', %), myVar)`
@ -366,7 +366,9 @@ describe('testing math operators', () => {
const removedUnaryExpRootSketch = removedUnaryExpRoot.part001
// without the minus sign, the y value should be 8
expect(removedUnaryExpRootSketch.value?.[1]?.to).toEqual([6, 8])
expect((removedUnaryExpRootSketch as SketchGroup).value?.[1]?.to).toEqual([
6, 8,
])
})
it('with nested callExpression and binaryExpression', async () => {
const code = 'const myVar = 2 + min(100, -1 + legLen(5, 3))'
@ -397,7 +399,10 @@ show(theExtrude)`
// helpers
async function exe(code: string, programMemory: ProgramMemory = { root: {} }) {
async function exe(
code: string,
programMemory: ProgramMemory = { root: {}, return: null }
) {
const ast = parser_wasm(code)
const result = await enginelessExecutor(ast, programMemory)

View File

@ -5,96 +5,21 @@ import {
SourceRangeMap,
} from './std/engineConnection'
import { ProgramReturn } from '../wasm-lib/kcl/bindings/ProgramReturn'
import { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
import { execute_wasm } from '../wasm-lib/pkg/wasm_lib'
import { KCLError } from './errors'
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
import { rangeTypeFix } from './abstractSyntaxTree'
export type SourceRange = [number, number]
export type PathToNode = [string | number, string][] // [pathKey, nodeType][]
export type Metadata = {
sourceRange: SourceRange
}
export type Position = [number, number, number]
export type Rotation = [number, number, number, number]
export type { SourceRange } from '../wasm-lib/kcl/bindings/SourceRange'
export type { Position } from '../wasm-lib/kcl/bindings/Position'
export type { Rotation } from '../wasm-lib/kcl/bindings/Rotation'
export type { Path } from '../wasm-lib/kcl/bindings/Path'
export type { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup'
export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface'
interface BasePath {
from: [number, number]
to: [number, number]
name?: string
__geoMeta: {
id: string
sourceRange: SourceRange
}
}
export interface ToPoint extends BasePath {
type: 'toPoint'
}
export interface Base extends BasePath {
type: 'base'
}
export interface HorizontalLineTo extends BasePath {
type: 'horizontalLineTo'
x: number
}
export interface AngledLineTo extends BasePath {
type: 'angledLineTo'
angle: number
x?: number
y?: number
}
interface GeoMeta {
__geoMeta: {
id: string
sourceRange: SourceRange
}
}
export type Path = ToPoint | HorizontalLineTo | AngledLineTo | Base
export interface SketchGroup {
type: 'sketchGroup'
id: string
value: Path[]
start?: Base
position: Position
rotation: Rotation
__meta: Metadata[]
}
interface ExtrudePlane {
type: 'extrudePlane'
position: Position
rotation: Rotation
name?: string
}
export type ExtrudeSurface = GeoMeta &
ExtrudePlane /* | ExtrudeRadius | ExtrudeSpline */
export interface ExtrudeGroup {
type: 'extrudeGroup'
id: string
value: ExtrudeSurface[]
height: number
position: Position
rotation: Rotation
__meta: Metadata[]
}
/** UserVal not produced by one of our internal functions */
export interface UserVal {
type: 'userVal'
value: any
__meta: Metadata[]
}
type MemoryItem = UserVal | SketchGroup | ExtrudeGroup
export type PathToNode = [string | number, string][]
interface Memory {
[key: string]: MemoryItem
@ -102,12 +27,12 @@ interface Memory {
export interface ProgramMemory {
root: Memory
return?: ProgramReturn
return: ProgramReturn | null
}
export const executor = async (
node: Program,
programMemory: ProgramMemory = { root: {} },
programMemory: ProgramMemory = { root: {}, return: null },
engineCommandManager: EngineCommandManager,
// work around while the gemotry is still be stored on the frontend
// will be removed when the stream UI is added.
@ -132,7 +57,7 @@ export const executor = async (
export const _executor = async (
node: Program,
programMemory: ProgramMemory = { root: {} },
programMemory: ProgramMemory = { root: {}, return: null },
engineCommandManager: EngineCommandManager
): Promise<ProgramMemory> => {
try {

View File

@ -770,7 +770,8 @@ export class EngineCommandManager {
if (command.type !== 'modeling_cmd_req') return Promise.resolve()
const cmd = command.cmd
if (
cmd.type === 'camera_drag_move' &&
(cmd.type === 'camera_drag_move' ||
cmd.type === 'handle_mouse_drag_move') &&
this.engineConnection?.unreliableDataChannel
) {
cmd.sequence = this.outSequence

View File

@ -4,6 +4,7 @@ import {
SketchGroup,
SourceRange,
PathToNode,
MemoryItem,
} from '../executor'
import {
Program,
@ -197,7 +198,7 @@ export const line: SketchLineHelper = {
)
const variableName = varDec.id.name
const sketch = previousProgramMemory?.root?.[variableName]
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
if (sketch.type !== 'SketchGroup') throw new Error('not a SketchGroup')
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
@ -538,7 +539,7 @@ export const angledLineOfXLength: SketchLineHelper = {
)
const variableName = varDec.id.name
const sketch = previousProgramMemory?.root?.[variableName]
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
if (sketch.type !== 'SketchGroup') throw new Error('not a SketchGroup')
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
const newLine = createCallback
@ -611,7 +612,7 @@ export const angledLineOfYLength: SketchLineHelper = {
)
const variableName = varDec.id.name
const sketch = previousProgramMemory?.root?.[variableName]
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
if (sketch.type !== 'SketchGroup') throw new Error('not a SketchGroup')
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
@ -868,7 +869,7 @@ export const angledLineThatIntersects: SketchLineHelper = {
const varName = varDec.declarations[0].id.name
const sketchGroup = previousProgramMemory.root[varName] as SketchGroup
const intersectPath = sketchGroup.value.find(
({ name }) => name === intersectTagName
({ name }: Path) => name === intersectTagName
)
let offset = 0
if (intersectPath) {
@ -965,7 +966,7 @@ export function addNewSketchLn({
>(node, pathToNode, 'PipeExpression')
const variableName = varDec.id.name
const sketch = previousProgramMemory?.root?.[variableName]
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
if (sketch.type !== 'SketchGroup') throw new Error('not a SketchGroup')
const last = sketch.value[sketch.value.length - 1] || sketch.start
const from = last.to

View File

@ -401,6 +401,11 @@ show(part001)`
programMemory.root['part001'] as SketchGroup,
[index, index]
).segment
expect(segment).toEqual({ to: [0, 0.04], from: [0, 0.04], name: '' })
expect(segment).toEqual({
to: [0, 0.04],
from: [0, 0.04],
name: '',
type: 'base',
})
})
})

View File

@ -4,7 +4,7 @@ import {
VariableDeclarator,
CallExpression,
} from '../abstractSyntaxTreeTypes'
import { SketchGroup, SourceRange } from '../executor'
import { SketchGroup, SourceRange, Path } from '../executor'
export function getSketchSegmentFromSourceRange(
sketchGroup: SketchGroup,
@ -20,10 +20,10 @@ export function getSketchSegmentFromSourceRange(
startSourceRange[1] >= rangeEnd &&
sketchGroup.start
)
return { segment: sketchGroup.start, index: -1 }
return { segment: { ...sketchGroup.start, type: 'base' }, index: -1 }
const lineIndex = sketchGroup.value.findIndex(
({ __geoMeta: { sourceRange } }) =>
({ __geoMeta: { sourceRange } }: Path) =>
sourceRange[0] <= rangeStart && sourceRange[1] >= rangeEnd
)
const line = sketchGroup.value[lineIndex]

View File

@ -28,6 +28,7 @@ import { createFirstArg, getFirstArg, replaceSketchLine } from './sketch'
import { PathToNode, ProgramMemory } from '../executor'
import { getSketchSegmentFromSourceRange } from './sketchConstraints'
import { getAngle, roundOff, normaliseAngle } from '../../lib/utils'
import { MemoryItem } from 'wasm-lib/kcl/bindings/MemoryItem'
type LineInputsType =
| 'xAbsolute'
@ -1452,7 +1453,7 @@ export function transformAstSketchLines({
const varName = varDec.id.name
const sketchGroup = programMemory.root?.[varName]
if (!sketchGroup || sketchGroup.type !== 'sketchGroup')
if (!sketchGroup || sketchGroup.type !== 'SketchGroup')
throw new Error('not a sketch group')
const seg = getSketchSegmentFromSourceRange(sketchGroup, range).segment
const referencedSegment = referencedSegmentRange

View File

@ -49,7 +49,7 @@ class MockEngineCommandManager {
export async function enginelessExecutor(
ast: Program,
pm: ProgramMemory = { root: {} }
pm: ProgramMemory = { root: {}, return: null }
): Promise<ProgramMemory> {
const mockEngineCommandManager = new MockEngineCommandManager({
setIsStreamReady: () => {},
@ -64,7 +64,7 @@ export async function enginelessExecutor(
export async function executor(
ast: Program,
pm: ProgramMemory = { root: {} }
pm: ProgramMemory = { root: {}, return: null }
): Promise<ProgramMemory> {
const engineCommandManager = new EngineCommandManager({
setIsStreamReady: () => {},

View File

@ -360,7 +360,7 @@ export const useStore = create<StoreState>()(
setError: (error = '') => {
set({ errorState: { isError: !!error, error } })
},
programMemory: { root: {}, pendingMemory: {} },
programMemory: { root: {}, return: null },
setProgramMemory: (programMemory) => set({ programMemory }),
isShiftDown: false,
setIsShiftDown: (isShiftDown) => set({ isShiftDown }),

View File

@ -12,7 +12,7 @@ use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind, DocumentSymbol, R
use crate::{
engine::EngineConnection,
errors::{KclError, KclErrorDetails},
executor::{MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange},
executor::{MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange, UserVal},
parser::PIPE_OPERATOR,
};
@ -1082,23 +1082,23 @@ impl Literal {
impl From<Literal> for MemoryItem {
fn from(literal: Literal) -> Self {
MemoryItem::UserVal {
MemoryItem::UserVal(UserVal {
value: literal.value.clone(),
meta: vec![Metadata {
source_range: literal.into(),
}],
}
})
}
}
impl From<&Box<Literal>> for MemoryItem {
fn from(literal: &Box<Literal>) -> Self {
MemoryItem::UserVal {
MemoryItem::UserVal(UserVal {
value: literal.value.clone(),
meta: vec![Metadata {
source_range: literal.into(),
}],
}
})
}
}
@ -1245,12 +1245,12 @@ impl ArrayExpression {
results.push(result);
}
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(UserVal {
value: results.into(),
meta: vec![Metadata {
source_range: self.into(),
}],
})
}))
}
/// Rename all identifiers that have the old name to the new given name.
@ -1370,12 +1370,12 @@ impl ObjectExpression {
object.insert(property.key.name.clone(), result.get_json_value()?);
}
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(UserVal {
value: object.into(),
meta: vec![Metadata {
source_range: self.into(),
}],
})
}))
}
/// Rename all identifiers that have the old name to the new given name.
@ -1582,12 +1582,12 @@ impl MemberExpression {
if let serde_json::Value::Object(map) = object {
if let Some(value) = map.get(&property_name) {
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(UserVal {
value: value.clone(),
meta: vec![Metadata {
source_range: self.into(),
}],
})
}))
} else {
Err(KclError::UndefinedValue(KclErrorDetails {
message: format!("Property {} not found in object", property_name),
@ -1715,12 +1715,12 @@ impl BinaryExpression {
parse_json_value_as_string(&right_json_value),
) {
let value = serde_json::Value::String(format!("{}{}", left, right));
return Ok(MemoryItem::UserVal {
return Ok(MemoryItem::UserVal(UserVal {
value,
meta: vec![Metadata {
source_range: self.into(),
}],
});
}));
}
}
@ -1735,12 +1735,12 @@ impl BinaryExpression {
BinaryOperator::Mod => (left % right).into(),
};
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(UserVal {
value,
meta: vec![Metadata {
source_range: self.into(),
}],
})
}))
}
/// Rename all identifiers that have the old name to the new given name.
@ -1845,12 +1845,12 @@ impl UnaryExpression {
.get_json_value()?,
self.into(),
)?;
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(UserVal {
value: (-(num)).into(),
meta: vec![Metadata {
source_range: self.into(),
}],
})
}))
}
/// Returns a hover value that includes the given character position.

View File

@ -98,16 +98,14 @@ impl ProgramReturn {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
#[serde(tag = "type")]
pub enum MemoryItem {
UserVal {
value: serde_json::Value,
#[serde(rename = "__meta")]
meta: Vec<Metadata>,
},
UserVal(UserVal),
SketchGroup(SketchGroup),
ExtrudeGroup(ExtrudeGroup),
#[ts(skip)]
ExtrudeTransform(ExtrudeTransform),
#[ts(skip)]
Function {
#[serde(skip)]
func: Option<MemoryFunction>,
@ -119,7 +117,16 @@ pub enum MemoryItem {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct UserVal {
pub value: serde_json::Value,
#[serde(rename = "__meta")]
pub meta: Vec<Metadata>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct ExtrudeTransform {
pub position: Position,
pub rotation: Rotation,
@ -138,7 +145,7 @@ pub type MemoryFunction = fn(
impl From<MemoryItem> for Vec<SourceRange> {
fn from(item: MemoryItem) -> Self {
match item {
MemoryItem::UserVal { meta, .. } => meta.iter().map(|m| m.source_range).collect(),
MemoryItem::UserVal(u) => u.meta.iter().map(|m| m.source_range).collect(),
MemoryItem::SketchGroup(s) => s.meta.iter().map(|m| m.source_range).collect(),
MemoryItem::ExtrudeGroup(e) => e.meta.iter().map(|m| m.source_range).collect(),
MemoryItem::ExtrudeTransform(e) => e.meta.iter().map(|m| m.source_range).collect(),
@ -149,8 +156,8 @@ impl From<MemoryItem> for Vec<SourceRange> {
impl MemoryItem {
pub fn get_json_value(&self) -> Result<serde_json::Value, KclError> {
if let MemoryItem::UserVal { value, .. } = self {
Ok(value.clone())
if let MemoryItem::UserVal(user_val) = self {
Ok(user_val.value.clone())
} else {
Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a user value: {:?}", self),
@ -186,7 +193,7 @@ impl MemoryItem {
/// A sketch group is a collection of paths.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct SketchGroup {
/// The id of the sketch group.
pub id: uuid::Uuid,
@ -238,7 +245,7 @@ impl SketchGroup {
/// An extrude group is a collection of extrude surfaces.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct ExtrudeGroup {
/// The id of the extrude group.
pub id: uuid::Uuid,
@ -276,15 +283,15 @@ pub enum BodyType {
#[derive(Debug, Deserialize, Serialize, PartialEq, Copy, Clone, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct Position(pub [f64; 3]);
pub struct Position(#[ts(type = "[number, number, number]")] pub [f64; 3]);
#[derive(Debug, Deserialize, Serialize, PartialEq, Copy, Clone, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct Rotation(pub [f64; 4]);
pub struct Rotation(#[ts(type = "[number, number, number, number]")] pub [f64; 4]);
#[derive(Debug, Default, Deserialize, Serialize, PartialEq, Copy, Clone, ts_rs::TS, JsonSchema, Hash, Eq)]
#[ts(export)]
pub struct SourceRange(pub [usize; 2]);
pub struct SourceRange(#[ts(type = "[number, number]")] pub [usize; 2]);
impl SourceRange {
/// Create a new source range.
@ -401,8 +408,10 @@ impl From<SourceRange> for Metadata {
#[serde(rename_all = "camelCase")]
pub struct BasePath {
/// The from point.
#[ts(type = "[number, number]")]
pub from: [f64; 2],
/// The to point.
#[ts(type = "[number, number]")]
pub to: [f64; 2],
/// The name of the path.
pub name: String,

View File

@ -103,12 +103,12 @@ impl<'a> Args<'a> {
}
fn make_user_val_from_json(&self, j: serde_json::Value) -> Result<MemoryItem, KclError> {
Ok(MemoryItem::UserVal {
Ok(MemoryItem::UserVal(crate::executor::UserVal {
value: j,
meta: vec![Metadata {
source_range: self.source_range,
}],
})
}))
}
fn make_user_val_from_f64(&self, f: f64) -> Result<MemoryItem, KclError> {