Helper functions for meta settings (get/update) (#5200)
* get the units back out Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * edit Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * add to wasmts Signed-off-by: Jess Frazelle <github@jessfraz.com> * fmt Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
		@ -18,6 +18,7 @@ import {
 | 
			
		||||
  default_project_settings,
 | 
			
		||||
  base64_decode,
 | 
			
		||||
  clear_scene_and_bust_cache,
 | 
			
		||||
  change_kcl_settings,
 | 
			
		||||
  reloadModule,
 | 
			
		||||
} from 'lib/wasm_lib_wrapper'
 | 
			
		||||
 | 
			
		||||
@ -56,6 +57,7 @@ import { ArtifactGraph as RustArtifactGraph } from 'wasm-lib/kcl/bindings/Artifa
 | 
			
		||||
import { Artifact } from './std/artifactGraph'
 | 
			
		||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
 | 
			
		||||
import { NumericSuffix } from 'wasm-lib/kcl/bindings/NumericSuffix'
 | 
			
		||||
import { MetaSettings } from 'wasm-lib/kcl/bindings/MetaSettings'
 | 
			
		||||
 | 
			
		||||
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
 | 
			
		||||
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
 | 
			
		||||
@ -844,3 +846,17 @@ export function base64Decode(base64: string): ArrayBuffer | Error {
 | 
			
		||||
    return new Error('Caught error decoding base64 string: ' + e)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Change the meta settings for the kcl file.
 | 
			
		||||
/// Returns the new kcl string with the updated settings.
 | 
			
		||||
export function changeKclSettings(
 | 
			
		||||
  kcl: string,
 | 
			
		||||
  settings: MetaSettings
 | 
			
		||||
): string | Error {
 | 
			
		||||
  try {
 | 
			
		||||
    return change_kcl_settings(kcl, JSON.stringify(settings))
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error('Caught error changing kcl settings: ' + e)
 | 
			
		||||
    return new Error('Caught error changing kcl settings: ' + e)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import {
 | 
			
		||||
  default_project_settings as DefaultProjectSettings,
 | 
			
		||||
  base64_decode as Base64Decode,
 | 
			
		||||
  clear_scene_and_bust_cache as ClearSceneAndBustCache,
 | 
			
		||||
  change_kcl_settings as ChangeKclSettings,
 | 
			
		||||
} from '../wasm-lib/pkg/wasm_lib'
 | 
			
		||||
 | 
			
		||||
type ModuleType = typeof import('../wasm-lib/pkg/wasm_lib')
 | 
			
		||||
@ -110,3 +111,6 @@ export const clear_scene_and_bust_cache: typeof ClearSceneAndBustCache = (
 | 
			
		||||
) => {
 | 
			
		||||
  return getModule().clear_scene_and_bust_cache(...args)
 | 
			
		||||
}
 | 
			
		||||
export const change_kcl_settings: typeof ChangeKclSettings = (...args) => {
 | 
			
		||||
  return getModule().change_kcl_settings(...args)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								src/wasm-lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								src/wasm-lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -1710,7 +1710,7 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "kcl-lib"
 | 
			
		||||
version = "0.2.32"
 | 
			
		||||
version = "0.2.33"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anyhow",
 | 
			
		||||
 "approx 0.5.1",
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "kcl-lib"
 | 
			
		||||
description = "KittyCAD Language implementation and tools"
 | 
			
		||||
version = "0.2.32"
 | 
			
		||||
version = "0.2.33"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
license = "MIT"
 | 
			
		||||
repository = "https://github.com/KittyCAD/modeling-app"
 | 
			
		||||
 | 
			
		||||
@ -13,9 +13,7 @@ use tower_lsp::lsp_types::{
 | 
			
		||||
    MarkupKind, ParameterInformation, ParameterLabel, SignatureHelp, SignatureInformation,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::execution::Sketch;
 | 
			
		||||
 | 
			
		||||
use crate::std::Primitive;
 | 
			
		||||
use crate::{execution::Sketch, std::Primitive};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
 | 
			
		||||
@ -7,9 +7,9 @@ use crate::{
 | 
			
		||||
    KclError, SourceRange,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) const SETTINGS: &str = "settings";
 | 
			
		||||
pub(super) const SETTINGS_UNIT_LENGTH: &str = "defaultLengthUnit";
 | 
			
		||||
pub(super) const SETTINGS_UNIT_ANGLE: &str = "defaultAngleUnit";
 | 
			
		||||
pub(crate) const SETTINGS: &str = "settings";
 | 
			
		||||
pub(crate) const SETTINGS_UNIT_LENGTH: &str = "defaultLengthUnit";
 | 
			
		||||
pub(crate) const SETTINGS_UNIT_ANGLE: &str = "defaultAngleUnit";
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 | 
			
		||||
pub(super) enum AnnotationScope {
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
use async_recursion::async_recursion;
 | 
			
		||||
 | 
			
		||||
use super::cad_op::{OpArg, Operation};
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
    execution::{
 | 
			
		||||
@ -19,8 +20,6 @@ use crate::{
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::cad_op::{OpArg, Operation};
 | 
			
		||||
 | 
			
		||||
impl BinaryPart {
 | 
			
		||||
    #[async_recursion]
 | 
			
		||||
    pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ use kittycad_modeling_cmds as kcmc;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use uuid::Uuid;
 | 
			
		||||
 | 
			
		||||
use super::ExecutorContext;
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
    execution::{ExecState, ImportedGeometry},
 | 
			
		||||
@ -22,8 +23,6 @@ use crate::{
 | 
			
		||||
    source_range::SourceRange,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::ExecutorContext;
 | 
			
		||||
 | 
			
		||||
// Zoo co-ordinate system.
 | 
			
		||||
//
 | 
			
		||||
// * Forward: -Y
 | 
			
		||||
 | 
			
		||||
@ -581,10 +581,11 @@ impl KclValue {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO called UnitLen so as not to clash with UnitLength in settings)
 | 
			
		||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
 | 
			
		||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
#[serde(tag = "type")]
 | 
			
		||||
pub enum UnitLen {
 | 
			
		||||
    #[default]
 | 
			
		||||
    Mm,
 | 
			
		||||
    Cm,
 | 
			
		||||
    M,
 | 
			
		||||
@ -593,6 +594,19 @@ pub enum UnitLen {
 | 
			
		||||
    Yards,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl std::fmt::Display for UnitLen {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            UnitLen::Mm => write!(f, "mm"),
 | 
			
		||||
            UnitLen::Cm => write!(f, "cm"),
 | 
			
		||||
            UnitLen::M => write!(f, "m"),
 | 
			
		||||
            UnitLen::Inches => write!(f, "in"),
 | 
			
		||||
            UnitLen::Feet => write!(f, "ft"),
 | 
			
		||||
            UnitLen::Yards => write!(f, "yd"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TryFrom<NumericSuffix> for UnitLen {
 | 
			
		||||
    type Error = ();
 | 
			
		||||
 | 
			
		||||
@ -644,6 +658,15 @@ pub enum UnitAngle {
 | 
			
		||||
    Radians,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl std::fmt::Display for UnitAngle {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            UnitAngle::Degrees => write!(f, "deg"),
 | 
			
		||||
            UnitAngle::Radians => write!(f, "rad"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TryFrom<NumericSuffix> for UnitAngle {
 | 
			
		||||
    type Error = ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,7 @@ use kcmc::{
 | 
			
		||||
    websocket::{ModelingSessionData, OkWebSocketResponseData},
 | 
			
		||||
    ImageFormat, ModelingCmd,
 | 
			
		||||
};
 | 
			
		||||
use kittycad_modeling_cmds::length_unit::LengthUnit;
 | 
			
		||||
use kittycad_modeling_cmds::{self as kcmc, websocket::WebSocketResponse};
 | 
			
		||||
use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, websocket::WebSocketResponse};
 | 
			
		||||
use parse_display::{Display, FromStr};
 | 
			
		||||
use schemars::JsonSchema;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
@ -27,14 +26,18 @@ pub(crate) use import::{import_foreign, send_to_engine as send_import_to_engine,
 | 
			
		||||
pub use kcl_value::{KclObjectFields, KclValue, UnitAngle, UnitLen};
 | 
			
		||||
use uuid::Uuid;
 | 
			
		||||
 | 
			
		||||
mod annotations;
 | 
			
		||||
pub(crate) mod annotations;
 | 
			
		||||
mod artifact;
 | 
			
		||||
pub(crate) mod cache;
 | 
			
		||||
mod cad_op;
 | 
			
		||||
mod exec_ast;
 | 
			
		||||
mod function_param;
 | 
			
		||||
mod import;
 | 
			
		||||
mod kcl_value;
 | 
			
		||||
pub(crate) mod kcl_value;
 | 
			
		||||
 | 
			
		||||
// Re-exports.
 | 
			
		||||
pub use artifact::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
 | 
			
		||||
pub use cad_op::Operation;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    engine::{EngineManager, ExecutionKind},
 | 
			
		||||
@ -52,10 +55,6 @@ use crate::{
 | 
			
		||||
    ExecError, KclErrorWithOutputs, Program,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Re-exports.
 | 
			
		||||
pub use artifact::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
 | 
			
		||||
pub use cad_op::Operation;
 | 
			
		||||
 | 
			
		||||
/// State for executing a program.
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
			
		||||
#[serde(rename_all = "camelCase")]
 | 
			
		||||
@ -247,7 +246,7 @@ impl ModuleState {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
 | 
			
		||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
#[serde(rename_all = "camelCase")]
 | 
			
		||||
pub struct MetaSettings {
 | 
			
		||||
@ -256,7 +255,11 @@ pub struct MetaSettings {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MetaSettings {
 | 
			
		||||
    fn update_from_annotation(&mut self, annotation: &NonCodeValue, source_range: SourceRange) -> Result<(), KclError> {
 | 
			
		||||
    pub fn update_from_annotation(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        annotation: &NonCodeValue,
 | 
			
		||||
        source_range: SourceRange,
 | 
			
		||||
    ) -> Result<(), KclError> {
 | 
			
		||||
        let properties = annotations::expect_properties(annotations::SETTINGS, annotation, source_range)?;
 | 
			
		||||
 | 
			
		||||
        for p in properties {
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,7 @@ pub use engine::{EngineManager, ExecutionKind};
 | 
			
		||||
pub use errors::{CompilationError, ConnectionError, ExecError, KclError, KclErrorWithOutputs};
 | 
			
		||||
pub use execution::{
 | 
			
		||||
    cache::{CacheInformation, OldAstState},
 | 
			
		||||
    ExecState, ExecutorContext, ExecutorSettings, Point2d,
 | 
			
		||||
    ExecState, ExecutorContext, ExecutorSettings, MetaSettings, Point2d,
 | 
			
		||||
};
 | 
			
		||||
pub use lsp::{
 | 
			
		||||
    copilot::Backend as CopilotLspBackend,
 | 
			
		||||
@ -121,8 +121,7 @@ pub mod std_utils {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub mod pretty {
 | 
			
		||||
    pub use crate::parsing::token::NumericSuffix;
 | 
			
		||||
    pub use crate::unparser::format_number;
 | 
			
		||||
    pub use crate::{parsing::token::NumericSuffix, unparser::format_number};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
@ -162,6 +161,18 @@ impl Program {
 | 
			
		||||
        self.ast.compute_digest()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get the meta settings for the kcl file from the annotations.
 | 
			
		||||
    pub fn get_meta_settings(&self) -> Result<Option<crate::MetaSettings>, KclError> {
 | 
			
		||||
        self.ast.get_meta_settings()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Change the meta settings for the kcl file.
 | 
			
		||||
    pub fn change_meta_settings(&mut self, settings: crate::MetaSettings) -> Result<Self, KclError> {
 | 
			
		||||
        Ok(Self {
 | 
			
		||||
            ast: self.ast.change_meta_settings(settings)?,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn lint_all(&self) -> Result<Vec<lint::Discovered>, anyhow::Error> {
 | 
			
		||||
        self.ast.lint_all()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ use kcmc::{
 | 
			
		||||
};
 | 
			
		||||
use kittycad_modeling_cmds as kcmc;
 | 
			
		||||
 | 
			
		||||
use super::types::LiteralValue;
 | 
			
		||||
use crate::{
 | 
			
		||||
    engine::EngineManager,
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
@ -18,8 +19,6 @@ use crate::{
 | 
			
		||||
    Program,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::types::LiteralValue;
 | 
			
		||||
 | 
			
		||||
type Point3d = kcmc::shared::Point3d<f64>;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,6 @@ use tower_lsp::lsp_types::{
 | 
			
		||||
    CompletionItem, CompletionItemKind, DocumentSymbol, FoldingRange, FoldingRangeKind, Range as LspRange, SymbolKind,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::digest::Digest;
 | 
			
		||||
pub use crate::parsing::ast::types::{
 | 
			
		||||
    condition::{ElseIf, IfExpression},
 | 
			
		||||
    literal_value::LiteralValue,
 | 
			
		||||
@ -26,7 +25,8 @@ pub use crate::parsing::ast::types::{
 | 
			
		||||
use crate::{
 | 
			
		||||
    docs::StdLibFn,
 | 
			
		||||
    errors::KclError,
 | 
			
		||||
    execution::{KclValue, Metadata, TagIdentifier},
 | 
			
		||||
    execution::{annotations, KclValue, Metadata, TagIdentifier},
 | 
			
		||||
    parsing::ast::digest::Digest,
 | 
			
		||||
    parsing::PIPE_OPERATOR,
 | 
			
		||||
    source_range::{ModuleId, SourceRange},
 | 
			
		||||
};
 | 
			
		||||
@ -254,6 +254,52 @@ impl Node<Program> {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(findings)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get the annotations for the meta settings from the kcl file.
 | 
			
		||||
    pub fn get_meta_settings(&self) -> Result<Option<crate::execution::MetaSettings>, KclError> {
 | 
			
		||||
        let annotations = self
 | 
			
		||||
            .non_code_meta
 | 
			
		||||
            .start_nodes
 | 
			
		||||
            .iter()
 | 
			
		||||
            .filter_map(|n| n.annotation().map(|result| (result, n.as_source_range())));
 | 
			
		||||
        for (annotation, source_range) in annotations {
 | 
			
		||||
            if annotation.annotation_name() == Some(annotations::SETTINGS) {
 | 
			
		||||
                let mut meta_settings = crate::execution::MetaSettings::default();
 | 
			
		||||
                meta_settings.update_from_annotation(annotation, source_range)?;
 | 
			
		||||
                return Ok(Some(meta_settings));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(None)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn change_meta_settings(&mut self, settings: crate::execution::MetaSettings) -> Result<Self, KclError> {
 | 
			
		||||
        let mut new_program = self.clone();
 | 
			
		||||
        let mut found = false;
 | 
			
		||||
        for node in &mut new_program.non_code_meta.start_nodes {
 | 
			
		||||
            if let Some(annotation) = node.annotation() {
 | 
			
		||||
                if annotation.annotation_name() == Some(annotations::SETTINGS) {
 | 
			
		||||
                    let annotation = NonCodeValue::new_from_meta_settings(&settings);
 | 
			
		||||
                    *node = Node::no_src(NonCodeNode {
 | 
			
		||||
                        value: annotation,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    });
 | 
			
		||||
                    found = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if !found {
 | 
			
		||||
            let annotation = NonCodeValue::new_from_meta_settings(&settings);
 | 
			
		||||
            new_program.non_code_meta.start_nodes.push(Node::no_src(NonCodeNode {
 | 
			
		||||
                value: annotation,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(new_program)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Program {
 | 
			
		||||
@ -1078,6 +1124,24 @@ impl NonCodeValue {
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn new_from_meta_settings(settings: &crate::execution::MetaSettings) -> NonCodeValue {
 | 
			
		||||
        let mut properties: Vec<Node<ObjectProperty>> = vec![ObjectProperty::new(
 | 
			
		||||
            Identifier::new(annotations::SETTINGS_UNIT_LENGTH),
 | 
			
		||||
            Expr::Identifier(Box::new(Identifier::new(&settings.default_length_units.to_string()))),
 | 
			
		||||
        )];
 | 
			
		||||
 | 
			
		||||
        if settings.default_angle_units != Default::default() {
 | 
			
		||||
            properties.push(ObjectProperty::new(
 | 
			
		||||
                Identifier::new(annotations::SETTINGS_UNIT_ANGLE),
 | 
			
		||||
                Expr::Identifier(Box::new(Identifier::new(&settings.default_angle_units.to_string()))),
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
        NonCodeValue::Annotation {
 | 
			
		||||
            name: Identifier::new(annotations::SETTINGS),
 | 
			
		||||
            properties: Some(properties),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
 | 
			
		||||
@ -2337,6 +2401,14 @@ impl Node<ObjectProperty> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ObjectProperty {
 | 
			
		||||
    pub fn new(key: Node<Identifier>, value: Expr) -> Node<Self> {
 | 
			
		||||
        Node::no_src(Self {
 | 
			
		||||
            key,
 | 
			
		||||
            value,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns a hover value that includes the given character position.
 | 
			
		||||
    pub fn get_hover_value_for_position(&self, pos: usize, code: &str) -> Option<Hover> {
 | 
			
		||||
        let value_source_range: SourceRange = self.value.clone().into();
 | 
			
		||||
@ -3756,4 +3828,98 @@ const cylinder = startSketchOn('-XZ')
 | 
			
		||||
 | 
			
		||||
        assert_eq!(l.raw, "false");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_parse_get_meta_settings_inch() {
 | 
			
		||||
        let some_program_string = r#"@settings(defaultLengthUnit = inch)
 | 
			
		||||
 | 
			
		||||
startSketchOn('XY')"#;
 | 
			
		||||
        let program = crate::parsing::top_level_parse(some_program_string).unwrap();
 | 
			
		||||
        let result = program.get_meta_settings().unwrap();
 | 
			
		||||
        assert!(result.is_some());
 | 
			
		||||
        let meta_settings = result.unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            meta_settings.default_length_units,
 | 
			
		||||
            crate::execution::kcl_value::UnitLen::Inches
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_parse_get_meta_settings_inch_to_mm() {
 | 
			
		||||
        let some_program_string = r#"@settings(defaultLengthUnit = inch)
 | 
			
		||||
 | 
			
		||||
startSketchOn('XY')"#;
 | 
			
		||||
        let mut program = crate::parsing::top_level_parse(some_program_string).unwrap();
 | 
			
		||||
        let result = program.get_meta_settings().unwrap();
 | 
			
		||||
        assert!(result.is_some());
 | 
			
		||||
        let meta_settings = result.unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            meta_settings.default_length_units,
 | 
			
		||||
            crate::execution::kcl_value::UnitLen::Inches
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Edit the ast.
 | 
			
		||||
        let new_program = program
 | 
			
		||||
            .change_meta_settings(crate::execution::MetaSettings {
 | 
			
		||||
                default_length_units: crate::execution::kcl_value::UnitLen::Mm,
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            })
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        let result = new_program.get_meta_settings().unwrap();
 | 
			
		||||
        assert!(result.is_some());
 | 
			
		||||
        let meta_settings = result.unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            meta_settings.default_length_units,
 | 
			
		||||
            crate::execution::kcl_value::UnitLen::Mm
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let formatted = new_program.recast(&Default::default(), 0);
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            formatted,
 | 
			
		||||
            r#"@settings(defaultLengthUnit = mm)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
startSketchOn('XY')
 | 
			
		||||
"#
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_parse_get_meta_settings_nothing_to_mm() {
 | 
			
		||||
        let some_program_string = r#"startSketchOn('XY')"#;
 | 
			
		||||
        let mut program = crate::parsing::top_level_parse(some_program_string).unwrap();
 | 
			
		||||
        let result = program.get_meta_settings().unwrap();
 | 
			
		||||
        assert!(result.is_none());
 | 
			
		||||
 | 
			
		||||
        // Edit the ast.
 | 
			
		||||
        let new_program = program
 | 
			
		||||
            .change_meta_settings(crate::execution::MetaSettings {
 | 
			
		||||
                default_length_units: crate::execution::kcl_value::UnitLen::Mm,
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            })
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        let result = new_program.get_meta_settings().unwrap();
 | 
			
		||||
        assert!(result.is_some());
 | 
			
		||||
        let meta_settings = result.unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            meta_settings.default_length_units,
 | 
			
		||||
            crate::execution::kcl_value::UnitLen::Mm
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let formatted = new_program.recast(&Default::default(), 0);
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            formatted,
 | 
			
		||||
            r#"@settings(defaultLengthUnit = mm)
 | 
			
		||||
startSketchOn('XY')
 | 
			
		||||
"#
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,14 +3,13 @@
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use derive_docs::stdlib;
 | 
			
		||||
 | 
			
		||||
use super::args::FromArgs;
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
    execution::{ExecState, KclValue},
 | 
			
		||||
    std::Args,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::args::FromArgs;
 | 
			
		||||
 | 
			
		||||
/// Compute the remainder after dividing `num` by `div`.
 | 
			
		||||
/// If `num` is negative, the result will be too.
 | 
			
		||||
pub async fn rem(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
 | 
			
		||||
@ -11,12 +11,11 @@ use parse_display::{Display, FromStr};
 | 
			
		||||
use schemars::JsonSchema;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
use crate::execution::{Artifact, ArtifactId};
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
    execution::{
 | 
			
		||||
        BasePath, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d, Sketch, SketchSet, SketchSurface,
 | 
			
		||||
        Solid, TagEngineInfo, TagIdentifier,
 | 
			
		||||
        Artifact, ArtifactId, BasePath, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d, Sketch,
 | 
			
		||||
        SketchSet, SketchSurface, Solid, TagEngineInfo, TagIdentifier,
 | 
			
		||||
    },
 | 
			
		||||
    parsing::ast::types::TagNode,
 | 
			
		||||
    std::{
 | 
			
		||||
@ -2250,7 +2249,10 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
    use pretty_assertions::assert_eq;
 | 
			
		||||
 | 
			
		||||
    use crate::{execution::TagIdentifier, std::sketch::PlaneData, std::utils::calculate_circle_center};
 | 
			
		||||
    use crate::{
 | 
			
		||||
        execution::TagIdentifier,
 | 
			
		||||
        std::{sketch::PlaneData, utils::calculate_circle_center},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_deserialize_plane_data() {
 | 
			
		||||
 | 
			
		||||
@ -614,3 +614,18 @@ pub fn calculate_circle_from_3_points(ax: f64, ay: f64, bx: f64, by: f64, cx: f6
 | 
			
		||||
        radius: result.radius,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Takes a kcl string and Meta settings and changes the meta settings in the kcl string.
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result<String, String> {
 | 
			
		||||
    console_error_panic_hook::set_once();
 | 
			
		||||
 | 
			
		||||
    let settings: kcl_lib::MetaSettings = serde_json::from_str(settings_str).map_err(|e| e.to_string())?;
 | 
			
		||||
    let mut program = Program::parse_no_errs(code).map_err(|e| e.to_string())?;
 | 
			
		||||
 | 
			
		||||
    let new_program = program.change_meta_settings(settings).map_err(|e| e.to_string())?;
 | 
			
		||||
 | 
			
		||||
    let formatted = new_program.recast();
 | 
			
		||||
 | 
			
		||||
    Ok(formatted)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user