-
-
Notifications
You must be signed in to change notification settings - Fork 115
feat/implementing pattern matching, enums, and optionals into hql #327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request implements pattern matching, enums, and optionals into HQL. The changes include adding optional syntax (?
) for query parameters and schema fields, support for enum definitions and pattern matching operations, schema versioning with migration support, and type casting improvements.
- Adds optional field/parameter syntax using
?
notation - Implements enum support and pattern matching with
MATCH
expressions - Introduces schema versioning system with automatic migrations
- Enhances type casting and value conversion capabilities
Reviewed Changes
Copilot reviewed 63 out of 63 changed files in this pull request and generated 16 comments.
Show a summary per file
File | Description |
---|---|
hql-tests/file56/file56.hx | Updates query parameter to be optional using ? syntax |
hql-tests/file59/schema.hx | Implements schema versioning with migration example |
hql-tests/file57/schema.hx | Adds vector embedding schema definition |
hql-tests/file57/file57.hx | Creates embedding queries with model annotations |
hql-tests/file51/schema.hx | Defines versioned schemas with field changes |
hql-tests/file51/migrations.hx | Implements schema migration logic |
helix-macros/src/lib.rs | Adds migration macro for schema transitions |
helix-db/src/utils/items.rs | Adds version field to Node and Edge structs |
helix-db/src/utils/id.rs | Enhances ID type with string conversion and ordering |
helix-db/src/protocol/value.rs | Implements comprehensive type casting system |
helix-db/src/protocol/date.rs | Adds DateError type for better error handling |
helix-macros/src/lib.rs
Outdated
let fn_name = &input_fn.sig.ident; | ||
let fn_name_str = fn_name.to_string(); | ||
|
||
println!("fn_name_str: {fn_name_str}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug print statement should be removed from production code. This println! will output to console during compilation and should be replaced with proper logging or removed entirely.
println!("fn_name_str: {fn_name_str}"); |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
Value::F32(i) => i as i8, | ||
Value::F64(i) => i as i8, | ||
Value::Boolean(i) => i as i8, | ||
Value::String(s) => s.parse::<i8>().unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on string parsing can cause panics with invalid input. Consider returning a Result or providing better error handling with a descriptive error message.
Value::String(s) => s.parse::<i8>().unwrap(), | |
Value::String(s) => s.parse::<i8>().expect(&format!("Failed to parse i8 from string: {}", s)), |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
Value::F32(i) => i as i16, | ||
Value::F64(i) => i as i16, | ||
Value::Boolean(i) => i as i16, | ||
Value::String(s) => s.parse::<i16>().unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on string parsing can cause panics with invalid input. Consider returning a Result or providing better error handling with a descriptive error message.
Value::String(s) => s.parse::<i16>().unwrap(), | |
Value::String(s) => s.parse::<i16>().expect(&format!("Failed to parse '{}' as i16", s)), |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
Value::F32(i) => i as i32, | ||
Value::F64(i) => i as i32, | ||
Value::Boolean(i) => i as i32, | ||
Value::String(s) => s.parse::<i32>().unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on string parsing can cause panics with invalid input. Consider returning a Result or providing better error handling with a descriptive error message.
Value::String(s) => s.parse::<i32>().unwrap(), | |
Value::String(s) => s.parse::<i32>().expect("Value::String cannot be parsed as i32"), |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
fn into_i32(self) -> i32 { | ||
match self { | ||
Value::I32(i) => i, | ||
Value::I8(i) => i as i32, | ||
Value::I16(i) => i as i32, | ||
Value::I64(i) => i as i32, | ||
Value::U8(i) => i as i32, | ||
Value::U16(i) => i as i32, | ||
Value::U32(i) => i as i32, | ||
Value::U64(i) => i as i32, | ||
Value::U128(i) => i as i32, | ||
Value::F32(i) => i as i32, | ||
Value::F64(i) => i as i32, | ||
Value::Boolean(i) => i as i32, | ||
Value::String(s) => s.parse::<i32>().unwrap(), | ||
_ => panic!("Value cannot be cast to i32"), | ||
} | ||
} | ||
fn into_i64(self) -> i64 { | ||
match self { | ||
Value::I64(i) => i, | ||
Value::I8(i) => i as i64, | ||
Value::I16(i) => i as i64, | ||
Value::I32(i) => i as i64, | ||
Value::U8(i) => i as i64, | ||
Value::U16(i) => i as i64, | ||
Value::U32(i) => i as i64, | ||
Value::U64(i) => i as i64, | ||
Value::U128(i) => i as i64, | ||
Value::F32(i) => i as i64, | ||
Value::F64(i) => i as i64, | ||
Value::Boolean(i) => i as i64, | ||
Value::String(s) => s.parse::<i64>().unwrap(), | ||
_ => panic!("Value cannot be cast to i64"), | ||
} | ||
} | ||
|
||
fn into_u8(self) -> u8 { | ||
match self { | ||
Value::U8(i) => i, | ||
Value::I8(i) => i as u8, | ||
Value::I16(i) => i as u8, | ||
Value::I32(i) => i as u8, | ||
Value::I64(i) => i as u8, | ||
Value::U16(i) => i as u8, | ||
Value::U32(i) => i as u8, | ||
Value::U64(i) => i as u8, | ||
Value::U128(i) => i as u8, | ||
Value::F32(i) => i as u8, | ||
Value::F64(i) => i as u8, | ||
Value::Boolean(i) => i as u8, | ||
Value::String(s) => s.parse::<u8>().unwrap(), | ||
_ => panic!("Value cannot be cast to u8"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on string parsing can cause panics with invalid input. Consider returning a Result or providing better error handling with a descriptive error message.
fn into_i32(self) -> i32 { | |
match self { | |
Value::I32(i) => i, | |
Value::I8(i) => i as i32, | |
Value::I16(i) => i as i32, | |
Value::I64(i) => i as i32, | |
Value::U8(i) => i as i32, | |
Value::U16(i) => i as i32, | |
Value::U32(i) => i as i32, | |
Value::U64(i) => i as i32, | |
Value::U128(i) => i as i32, | |
Value::F32(i) => i as i32, | |
Value::F64(i) => i as i32, | |
Value::Boolean(i) => i as i32, | |
Value::String(s) => s.parse::<i32>().unwrap(), | |
_ => panic!("Value cannot be cast to i32"), | |
} | |
} | |
fn into_i64(self) -> i64 { | |
match self { | |
Value::I64(i) => i, | |
Value::I8(i) => i as i64, | |
Value::I16(i) => i as i64, | |
Value::I32(i) => i as i64, | |
Value::U8(i) => i as i64, | |
Value::U16(i) => i as i64, | |
Value::U32(i) => i as i64, | |
Value::U64(i) => i as i64, | |
Value::U128(i) => i as i64, | |
Value::F32(i) => i as i64, | |
Value::F64(i) => i as i64, | |
Value::Boolean(i) => i as i64, | |
Value::String(s) => s.parse::<i64>().unwrap(), | |
_ => panic!("Value cannot be cast to i64"), | |
} | |
} | |
fn into_u8(self) -> u8 { | |
match self { | |
Value::U8(i) => i, | |
Value::I8(i) => i as u8, | |
Value::I16(i) => i as u8, | |
Value::I32(i) => i as u8, | |
Value::I64(i) => i as u8, | |
Value::U16(i) => i as u8, | |
Value::U32(i) => i as u8, | |
Value::U64(i) => i as u8, | |
Value::U128(i) => i as u8, | |
Value::F32(i) => i as u8, | |
Value::F64(i) => i as u8, | |
Value::Boolean(i) => i as u8, | |
Value::String(s) => s.parse::<u8>().unwrap(), | |
_ => panic!("Value cannot be cast to u8"), | |
fn into_i32(self) -> Result<i32, GraphError> { | |
match self { | |
Value::I32(i) => Ok(i), | |
Value::I8(i) => Ok(i as i32), | |
Value::I16(i) => Ok(i as i32), | |
Value::I64(i) => Ok(i as i32), | |
Value::U8(i) => Ok(i as i32), | |
Value::U16(i) => Ok(i as i32), | |
Value::U32(i) => Ok(i as i32), | |
Value::U64(i) => Ok(i as i32), | |
Value::U128(i) => Ok(i as i32), | |
Value::F32(i) => Ok(i as i32), | |
Value::F64(i) => Ok(i as i32), | |
Value::Boolean(i) => Ok(i as i32), | |
Value::String(s) => s.parse::<i32>().map_err(|e| GraphError::ConversionError(format!("Failed to parse string '{}' as i32: {}", s, e))), | |
_ => Err(GraphError::ConversionError("Value cannot be cast to i32".to_string())), | |
} | |
} | |
fn into_i64(self) -> Result<i64, GraphError> { | |
match self { | |
Value::I64(i) => Ok(i), | |
Value::I8(i) => Ok(i as i64), | |
Value::I16(i) => Ok(i as i64), | |
Value::I32(i) => Ok(i as i64), | |
Value::U8(i) => Ok(i as i64), | |
Value::U16(i) => Ok(i as i64), | |
Value::U32(i) => Ok(i as i64), | |
Value::U64(i) => Ok(i as i64), | |
Value::U128(i) => Ok(i as i64), | |
Value::F32(i) => Ok(i as i64), | |
Value::F64(i) => Ok(i as i64), | |
Value::Boolean(i) => Ok(i as i64), | |
Value::String(s) => s.parse::<i64>().map_err(|e| GraphError::ConversionError(format!("Failed to parse string '{}' as i64: {}", s, e))), | |
_ => Err(GraphError::ConversionError("Value cannot be cast to i64".to_string())), | |
} | |
} | |
fn into_u8(self) -> Result<u8, GraphError> { | |
match self { | |
Value::U8(i) => Ok(i), | |
Value::I8(i) => Ok(i as u8), | |
Value::I16(i) => Ok(i as u8), | |
Value::I32(i) => Ok(i as u8), | |
Value::I64(i) => Ok(i as u8), | |
Value::U16(i) => Ok(i as u8), | |
Value::U32(i) => Ok(i as u8), | |
Value::U64(i) => Ok(i as u8), | |
Value::U128(i) => Ok(i as u8), | |
Value::F32(i) => Ok(i as u8), | |
Value::F64(i) => Ok(i as u8), | |
Value::Boolean(i) => Ok(i as u8), | |
Value::String(s) => s.parse::<u8>().map_err(|e| GraphError::ConversionError(format!("Failed to parse string '{}' as u8: {}", s, e))), | |
_ => Err(GraphError::ConversionError("Value cannot be cast to u8".to_string())), |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
Value::U32(i) => i as f64, | ||
Value::U64(i) => i as f64, | ||
Value::U128(i) => i as f64, | ||
Value::String(s) => s.parse::<f64>().unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on string parsing can cause panics with invalid input. Consider returning a Result or providing better error handling with a descriptive error message.
Value::String(s) => s.parse::<f64>().unwrap(), | |
Value::String(s) => s.parse::<f64>().expect("Value::String could not be parsed as f64"), |
Copilot uses AI. Check for mistakes.
helix-db/src/utils/id.rs
Outdated
impl From<String> for ID { | ||
fn from(id: String) -> Self { | ||
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | ||
} | ||
} | ||
impl From<&String> for ID { | ||
fn from(id: &String) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | ||
} | ||
} | ||
|
||
impl From<&str> for ID { | ||
fn from(id: &str) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on UUID parsing can cause panics with malformed UUIDs. Consider returning a Result or providing better error handling with a descriptive error message.
impl From<String> for ID { | |
fn from(id: String) -> Self { | |
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | |
} | |
} | |
impl From<&String> for ID { | |
fn from(id: &String) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
} | |
} | |
impl From<&str> for ID { | |
fn from(id: &str) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
impl TryFrom<String> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: String) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(&id).map(|uuid| ID(uuid.as_u128())) | |
} | |
} | |
impl TryFrom<&String> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: &String) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(id).map(|uuid| ID(uuid.as_u128())) | |
} | |
} | |
impl TryFrom<&str> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: &str) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(id).map(|uuid| ID(uuid.as_u128())) |
Copilot uses AI. Check for mistakes.
helix-db/src/utils/id.rs
Outdated
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | ||
} | ||
} | ||
impl From<&String> for ID { | ||
fn from(id: &String) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | ||
} | ||
} | ||
|
||
impl From<&str> for ID { | ||
fn from(id: &str) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on UUID parsing can cause panics with malformed UUIDs. Consider returning a Result or providing better error handling with a descriptive error message.
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | |
} | |
} | |
impl From<&String> for ID { | |
fn from(id: &String) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
} | |
} | |
impl From<&str> for ID { | |
fn from(id: &str) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
} | |
} | |
ID(uuid::Uuid::parse_str(&id).expect("Invalid UUID string in ID conversion").as_u128()) | |
} | |
} | |
impl From<&String> for ID { | |
fn from(id: &String) -> Self { | |
ID(uuid::Uuid::parse_str(id).expect("Invalid UUID string in ID conversion").as_u128()) | |
} | |
} | |
impl From<&str> for ID { | |
fn from(id: &str) -> Self { | |
ID(uuid::Uuid::parse_str(id).expect("Invalid UUID string in ID conversion").as_u128()) | |
} | |
} | |
impl ID { | |
/// Attempts to create an ID from a UUID string, returning an error if the string is invalid. | |
pub fn try_from_str(id: &str) -> Result<Self, uuid::Error> { | |
uuid::Uuid::parse_str(id).map(|uuid| ID(uuid.as_u128())) | |
} | |
} |
Copilot uses AI. Check for mistakes.
helix-db/src/utils/id.rs
Outdated
impl From<String> for ID { | ||
fn from(id: String) -> Self { | ||
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | ||
} | ||
} | ||
impl From<&String> for ID { | ||
fn from(id: &String) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | ||
} | ||
} | ||
|
||
impl From<&str> for ID { | ||
fn from(id: &str) -> Self { | ||
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unwrap() on UUID parsing can cause panics with malformed UUIDs. Consider returning a Result or providing better error handling with a descriptive error message.
impl From<String> for ID { | |
fn from(id: String) -> Self { | |
ID(uuid::Uuid::parse_str(&id).unwrap().as_u128()) | |
} | |
} | |
impl From<&String> for ID { | |
fn from(id: &String) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
} | |
} | |
impl From<&str> for ID { | |
fn from(id: &str) -> Self { | |
ID(uuid::Uuid::parse_str(id).unwrap().as_u128()) | |
impl TryFrom<String> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: String) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(&id).map(|uuid| ID(uuid.as_u128())) | |
} | |
} | |
impl TryFrom<&String> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: &String) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(id).map(|uuid| ID(uuid.as_u128())) | |
} | |
} | |
impl TryFrom<&str> for ID { | |
type Error = uuid::Error; | |
fn try_from(id: &str) -> Result<Self, Self::Error> { | |
uuid::Uuid::parse_str(id).map(|uuid| ID(uuid.as_u128())) |
Copilot uses AI. Check for mistakes.
helix-db/src/protocol/value.rs
Outdated
impl CastValue for Value { | ||
fn into_i8(self) -> i8 { | ||
match self { | ||
Value::I8(i) => i, | ||
Value::I16(i) => i as i8, | ||
Value::I32(i) => i as i8, | ||
Value::I64(i) => i as i8, | ||
Value::U8(i) => i as i8, | ||
Value::U16(i) => i as i8, | ||
Value::U32(i) => i as i8, | ||
Value::U64(i) => i as i8, | ||
Value::U128(i) => i as i8, | ||
Value::F32(i) => i as i8, | ||
Value::F64(i) => i as i8, | ||
Value::Boolean(i) => i as i8, | ||
Value::String(s) => s.parse::<i8>().unwrap(), | ||
_ => panic!("Value cannot be cast to i8"), | ||
} | ||
} | ||
fn into_i16(self) -> i16 { | ||
match self { | ||
Value::I16(i) => i, | ||
Value::I8(i) => i as i16, | ||
Value::I32(i) => i as i16, | ||
Value::I64(i) => i as i16, | ||
Value::U8(i) => i as i16, | ||
Value::U16(i) => i as i16, | ||
Value::U32(i) => i as i16, | ||
Value::U64(i) => i as i16, | ||
Value::U128(i) => i as i16, | ||
Value::F32(i) => i as i16, | ||
Value::F64(i) => i as i16, | ||
Value::Boolean(i) => i as i16, | ||
Value::String(s) => s.parse::<i16>().unwrap(), | ||
_ => panic!("Value cannot be cast to i16"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using panic! for error handling is not ideal for production code. Consider returning a Result with a descriptive error message instead.
impl CastValue for Value { | |
fn into_i8(self) -> i8 { | |
match self { | |
Value::I8(i) => i, | |
Value::I16(i) => i as i8, | |
Value::I32(i) => i as i8, | |
Value::I64(i) => i as i8, | |
Value::U8(i) => i as i8, | |
Value::U16(i) => i as i8, | |
Value::U32(i) => i as i8, | |
Value::U64(i) => i as i8, | |
Value::U128(i) => i as i8, | |
Value::F32(i) => i as i8, | |
Value::F64(i) => i as i8, | |
Value::Boolean(i) => i as i8, | |
Value::String(s) => s.parse::<i8>().unwrap(), | |
_ => panic!("Value cannot be cast to i8"), | |
} | |
} | |
fn into_i16(self) -> i16 { | |
match self { | |
Value::I16(i) => i, | |
Value::I8(i) => i as i16, | |
Value::I32(i) => i as i16, | |
Value::I64(i) => i as i16, | |
Value::U8(i) => i as i16, | |
Value::U16(i) => i as i16, | |
Value::U32(i) => i as i16, | |
Value::U64(i) => i as i16, | |
Value::U128(i) => i as i16, | |
Value::F32(i) => i as i16, | |
Value::F64(i) => i as i16, | |
Value::Boolean(i) => i as i16, | |
Value::String(s) => s.parse::<i16>().unwrap(), | |
_ => panic!("Value cannot be cast to i16"), | |
// Error type for cast failures | |
#[derive(Debug)] | |
pub enum CastError { | |
InvalidType(String), | |
ParseError(String), | |
} | |
impl std::fmt::Display for CastError { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
match self { | |
CastError::InvalidType(msg) => write!(f, "Invalid type: {}", msg), | |
CastError::ParseError(msg) => write!(f, "Parse error: {}", msg), | |
} | |
} | |
} | |
impl std::error::Error for CastError {} | |
impl CastValue for Value { | |
fn into_i8(self) -> Result<i8, CastError> { | |
match self { | |
Value::I8(i) => Ok(i), | |
Value::I16(i) => Ok(i as i8), | |
Value::I32(i) => Ok(i as i8), | |
Value::I64(i) => Ok(i as i8), | |
Value::U8(i) => Ok(i as i8), | |
Value::U16(i) => Ok(i as i8), | |
Value::U32(i) => Ok(i as i8), | |
Value::U64(i) => Ok(i as i8), | |
Value::U128(i) => Ok(i as i8), | |
Value::F32(i) => Ok(i as i8), | |
Value::F64(i) => Ok(i as i8), | |
Value::Boolean(i) => Ok(i as i8), | |
Value::String(s) => s.parse::<i8>() | |
.map_err(|e| CastError::ParseError(format!("Failed to parse '{}' as i8: {}", s, e))), | |
_ => Err(CastError::InvalidType("Value cannot be cast to i8".to_string())), | |
} | |
} | |
fn into_i16(self) -> Result<i16, CastError> { | |
match self { | |
Value::I16(i) => Ok(i), | |
Value::I8(i) => Ok(i as i16), | |
Value::I32(i) => Ok(i as i16), | |
Value::I64(i) => Ok(i as i16), | |
Value::U8(i) => Ok(i as i16), | |
Value::U16(i) => Ok(i as i16), | |
Value::U32(i) => Ok(i as i16), | |
Value::U64(i) => Ok(i as i16), | |
Value::U128(i) => Ok(i as i16), | |
Value::F32(i) => Ok(i as i16), | |
Value::F64(i) => Ok(i as i16), | |
Value::Boolean(i) => Ok(i as i16), | |
Value::String(s) => s.parse::<i16>() | |
.map_err(|e| CastError::ParseError(format!("Failed to parse '{}' as i16: {}", s, e))), | |
_ => Err(CastError::InvalidType("Value cannot be cast to i16".to_string())), |
Copilot uses AI. Check for mistakes.
Description
implementing pattern matching, enums, and optionals into hql
for optionals
for enums
for pattern matching
Related Issues
Closes #
Checklist when merging to main
rustfmt
helix-cli/Cargo.toml
andhelixdb/Cargo.toml
Additional Notes