use crate::error::Error;
use crate::parser::Parser;
pub(crate) fn string_to_utf16be_bytes(value: &str) -> Vec<u8> {
let mut bytes = Vec::<u8>::new();
for code_unit in value.encode_utf16() {
bytes.extend_from_slice(&code_unit.to_be_bytes());
}
bytes
}
pub(crate) fn string_to_utf16le_bytes(value: &str) -> Vec<u8> {
let mut bytes = Vec::<u8>::new();
for code_unit in value.encode_utf16() {
bytes.extend_from_slice(&code_unit.to_le_bytes());
}
bytes
}
pub(crate) fn utf16be_bytes_to_string(bytes: &[u8]) -> String {
let num_code_units = bytes.len() / 2;
let mut code_units = Vec::<u16>::with_capacity(num_code_units);
for i in 0..num_code_units {
let offset = i * 2;
let code_unit =
u16::from_be_bytes(bytes[offset..offset + 2].try_into().unwrap());
code_units.push(code_unit);
}
String::from_utf16(&code_units).unwrap()
}
pub(crate) fn utf16le_bytes_to_string(bytes: &[u8]) -> String {
let num_code_units = bytes.len() / 2;
let mut code_units = Vec::<u16>::with_capacity(num_code_units);
for i in 0..num_code_units {
let offset = i * 2;
let code_unit =
u16::from_le_bytes(bytes[offset..offset + 2].try_into().unwrap());
code_units.push(code_unit);
}
String::from_utf16(&code_units).unwrap()
}
pub fn enquote_literal(value: &str) -> String {
let mut result = String::new();
result.push('\'');
for ch in value.chars() {
result.push(ch);
if ch == '\'' {
result.push(ch);
}
}
result.push('\'');
result
}
pub fn enquote_name(value: &str, capitalize: bool) -> Result<String, Error> {
if value.contains('"') {
Err(Error::name_has_embedded_quotes())
} else {
let adjusted_value = if capitalize {
value.to_uppercase()
} else {
value.to_string()
};
Ok(format!("\"{}\"", adjusted_value))
}
}
pub fn is_qualified_sql_name(value: &str) -> bool {
let mut num_parts = 0;
let mut parser = Parser::new(value.trim());
while parser.parse_simple_sql_name().is_some() {
num_parts += 1;
parser.skip_whitespace();
let ch_opt = parser.next_char();
parser.skip_whitespace();
match ch_opt {
Some(ch) => {
if ch == '@' {
return parser.parse_simple_sql_name().is_some()
&& parser.next_char().is_none();
} else if ch != '.' {
return false;
}
}
None => break,
}
}
num_parts > 0 && parser.next_char().is_none()
}
pub fn is_simple_sql_name(value: &str) -> bool {
let mut parser = Parser::new(value.trim());
parser.parse_simple_sql_name().is_some() && parser.next_char().is_none()
}