Struct taos_query::common::Field
source · pub struct Field { /* private fields */ }
Expand description
A Field
represents the name and data type of one column or tag.
For example, a table as “create table tb1 (ts timestamp, n nchar(100))”.
When query with “select * from tb1”, you will get two fields:
{ name: "ts", ty: Timestamp, bytes: 8 }
, aTIMESTAMP
field with namets
, bytes length 8 which is the byte-width ofi64
.{ name: "n", ty: NChar, bytes: 100 }
, aNCHAR
filed with namen
, bytes length 100 which is the length of the variable-length data.
Implementations§
source§impl Field
impl Field
pub const fn empty() -> Self
sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
Field name.
Examples found in repository?
More examples
src/de/mod.rs (line 60)
52 53 54 55 56 57 58 59 60 61 62 63 64
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeSeed<'de>,
{
match self.inner.next() {
Some((field, value)) => {
self.value = Some(value);
let field = &*field;
seed.deserialize(field.name().into_deserializer()).map(Some)
}
_ => Ok(None),
}
}
src/common/field.rs (line 47)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
fn from(value: &Field) -> Self {
// let name = value.name().into_c_str().into_owned();
let name = value.name().as_bytes();
let mut field = c_field_t {
name: [0; 65],
type_: value.ty() as _,
bytes: value.bytes() as _,
};
unsafe {
std::ptr::copy_nonoverlapping(name.as_ptr(), field.name.as_mut_ptr() as _, name.len());
}
field
}
}
impl Inlinable for Field {
fn write_inlined<W: std::io::Write>(&self, wtr: &mut W) -> std::io::Result<usize> {
let mut l = wtr.write_u8_le(self.ty as u8)?;
l += wtr.write_u32_le(self.bytes)?;
l += wtr.write_inlined_str::<2>(&self.name)?;
Ok(l)
}
fn read_inlined<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let ty = Ty::from(reader.read_u8()?);
let bytes = reader.read_u32()?;
let name = reader.read_inlined_str::<2>()?;
Ok(Self { name, ty, bytes })
}
}
impl Field {
pub const fn empty() -> Self {
Self {
name: String::new(),
ty: Ty::Null,
bytes: 0,
}
}
pub fn new(name: impl Into<String>, ty: Ty, bytes: u32) -> Self {
let name = name.into();
Self { name, ty, bytes }
}
/// Field name.
pub fn name(&self) -> &str {
&self.name
}
/// Escaped file name
pub fn escaped_name(&self) -> String {
format!("`{}`", self.name())
}
/// Data type of the field.
pub const fn ty(&self) -> Ty {
self.ty
}
/// Preset length of variable length data type.
///
/// It's the byte-width in other types.
pub const fn bytes(&self) -> u32 {
self.bytes
}
pub fn to_c_field(&self) -> c_field_t {
self.into()
}
/// Represent the data type in sql.
///
/// For example: "INT", "VARCHAR(100)".
pub fn sql_repr(&self) -> String {
let ty = self.ty();
if ty.is_var_type() {
format!("`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
format!("`{}` {}", self.name(), ty.name())
}
}
}
impl Display for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ty = self.ty();
if ty.is_var_type() {
write!(f, "`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
write!(f, "`{}` {}", self.name(), ty.name())
}
}
src/common/raw/meta.rs (line 319)
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.alter_type {
AlterType::AddTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` ADD TAG {}",
self.table_name,
self.field.sql_repr()
)),
AlterType::DropTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` DROP TAG `{}`",
self.table_name,
self.field.name()
)),
AlterType::RenameTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` RENAME TAG `{}` `{}`",
self.table_name,
self.field.name(),
self.col_new_name.as_ref().unwrap()
)),
AlterType::SetTagValue => {
f.write_fmt(format_args!(
"ALTER TABLE `{}` SET TAG `{}` ",
self.table_name,
self.field.name()
))?;
if self.col_value_null.unwrap_or(false) {
f.write_str("NULL")
} else if self.field.ty.is_var_type() {
f.write_fmt(format_args!("'{}'", self.col_value.as_ref().unwrap()))
} else {
f.write_fmt(format_args!("{}", self.col_value.as_ref().unwrap()))
}
}
AlterType::AddColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` ADD COLUMN {}",
self.table_name,
self.field.sql_repr()
)),
AlterType::DropColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` DROP COLUMN `{}`",
self.table_name,
self.field.name()
)),
AlterType::ModifyColumnLength => f.write_fmt(format_args!(
"ALTER TABLE `{}` MODIFY COLUMN {}",
self.table_name,
self.field.sql_repr(),
)),
AlterType::ModifyTagLength => f.write_fmt(format_args!(
"ALTER TABLE `{}` MODIFY TAG {}",
self.table_name,
self.field.sql_repr(),
)),
AlterType::ModifyTableOption => todo!(),
AlterType::RenameColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` RENAME COLUMN `{}` `{}`",
self.table_name,
self.field.name(),
self.col_new_name.as_ref().unwrap()
)),
}
}
src/common/raw/mod.rs (line 417)
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
pub fn parse_from_raw_block_v2(
bytes: impl Into<Bytes>,
fields: &[Field],
lengths: &[u32],
rows: usize,
precision: Precision,
) -> Self {
use bytes::BufMut;
debug_assert_eq!(fields.len(), lengths.len());
const fn bool_is_null(v: *const bool) -> bool {
unsafe { *(v as *const u8) == 0x02 }
}
const fn tiny_int_is_null(v: *const i8) -> bool {
unsafe { *(v as *const u8) == 0x80 }
}
const fn small_int_is_null(v: *const i16) -> bool {
unsafe { *(v as *const u16) == 0x8000 }
}
const fn int_is_null(v: *const i32) -> bool {
unsafe { *(v as *const u32) == 0x80000000 }
}
const fn big_int_is_null(v: *const i64) -> bool {
unsafe { *(v as *const u64) == 0x8000000000000000 }
}
const fn u_tiny_int_is_null(v: *const u8) -> bool {
unsafe { *(v as *const u8) == 0xFF }
}
const fn u_small_int_is_null(v: *const u16) -> bool {
unsafe { *(v as *const u16) == 0xFFFF }
}
const fn u_int_is_null(v: *const u32) -> bool {
unsafe { *(v as *const u32) == 0xFFFFFFFF }
}
const fn u_big_int_is_null(v: *const u64) -> bool {
unsafe { *(v as *const u64) == 0xFFFFFFFFFFFFFFFF }
}
const fn float_is_null(v: *const f32) -> bool {
unsafe { *(v as *const u32) == 0x7FF00000 }
}
const fn double_is_null(v: *const f64) -> bool {
unsafe { *(v as *const u64) == 0x7FFFFF0000000000 }
}
// const BOOL_NULL: u8 = 0x2;
// const TINY_INT_NULL: i8 = i8::MIN;
// const SMALL_INT_NULL: i16 = i16::MIN;
// const INT_NULL: i32 = i32::MIN;
// const BIG_INT_NULL: i64 = i64::MIN;
// const FLOAT_NULL: f32 = 0x7FF00000i32 as f32;
// const DOUBLE_NULL: f64 = 0x7FFFFF0000000000i64 as f64;
// const U_TINY_INT_NULL: u8 = u8::MAX;
// const U_SMALL_INT_NULL: u16 = u16::MAX;
// const U_INT_NULL: u32 = u32::MAX;
// const U_BIG_INT_NULL: u64 = u64::MAX;
let layout = Arc::new(RefCell::new(
Layout::INLINE_DEFAULT.with_schema_changed().into(),
));
let bytes = bytes.into();
let cols = fields.len();
let mut schemas_bytes =
bytes::BytesMut::with_capacity(rows * std::mem::size_of::<ColSchema>());
fields
.iter()
.for_each(|f| schemas_bytes.put(f.to_column_schema().as_bytes()));
let schemas = Schemas::from(schemas_bytes);
let mut data_lengths = LengthsMut::new(cols);
let mut columns = Vec::new();
let mut offset = 0;
for (i, (field, length)) in fields.into_iter().zip(&*lengths).enumerate() {
macro_rules! _primitive_view {
($ty:ident, $prim:ty) => {{
debug_assert_eq!(field.bytes(), *length);
// column start
let start = offset;
// column end
offset += rows * std::mem::size_of::<$prim>() as usize;
// byte slice from start to end: `[start, end)`.
let data = bytes.slice(start..offset);
// value as target type
let value_slice = unsafe {
std::slice::from_raw_parts(
transmute::<*const u8, *const $prim>(data.as_ptr()),
rows,
)
};
// Set data lengths for v3-compatible block.
data_lengths[i] = data.len() as u32;
// generate nulls bitmap.
let nulls = NullsMut::from_bools(
value_slice
.iter()
.map(|v| paste::paste!{ [<$ty:snake _is_null>](v as _) })
// .map(|b| *b as u64 == paste::paste! { [<$ty:snake:upper _NULL>] }),
)
.into_nulls();
// build column view
let column = paste::paste! { ColumnView::$ty([<$ty View>] { nulls, data }) };
columns.push(column);
}};
}
match field.ty() {
Ty::Null => unreachable!(),
// Signed integers columns.
Ty::Bool => _primitive_view!(Bool, bool),
Ty::TinyInt => _primitive_view!(TinyInt, i8),
Ty::SmallInt => _primitive_view!(SmallInt, i16),
Ty::Int => _primitive_view!(Int, i32),
Ty::BigInt => _primitive_view!(BigInt, i64),
// Unsigned integers columns.
Ty::UTinyInt => _primitive_view!(UTinyInt, u8),
Ty::USmallInt => _primitive_view!(USmallInt, u16),
Ty::UInt => _primitive_view!(UInt, u32),
Ty::UBigInt => _primitive_view!(UBigInt, u64),
// Float columns.
Ty::Float => _primitive_view!(Float, f32),
Ty::Double => _primitive_view!(Double, f64),
Ty::VarChar => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 1 && *ptr.offset(2) == 0xFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::VarChar(VarCharView { offsets, data }));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::Timestamp => {
// column start
let start = offset;
// column end
offset += rows * std::mem::size_of::<i64>() as usize;
// byte slice from start to end: `[start, end)`.
let data = bytes.slice(start..offset);
// value as target type
let value_slice = unsafe {
std::slice::from_raw_parts(
transmute::<*const u8, *const i64>(data.as_ptr()),
rows,
)
};
// Set data lengths for v3-compatible block.
data_lengths[i] = data.len() as u32;
// generate nulls bitmap.
let nulls =
NullsMut::from_bools(value_slice.iter().map(|b| big_int_is_null(b as _)))
.into_nulls();
// build column view
let column = ColumnView::Timestamp(TimestampView {
nulls,
data,
precision,
});
columns.push(column);
}
Ty::NChar => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 4 && *(ptr.offset(2) as *const u32) == 0xFFFFFFFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::NChar(NCharView {
offsets,
data,
is_chars: UnsafeCell::new(false),
version: Version::V2,
layout: layout.clone(),
}));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::Json => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 4 && *(ptr.offset(2) as *const u32) == 0xFFFFFFFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::Json(JsonView { offsets, data }));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::VarBinary => todo!(),
Ty::Decimal => todo!(),
Ty::Blob => todo!(),
Ty::MediumBlob => todo!(),
}
}
Self {
layout,
version: Version::V2,
data: Cell::new(bytes),
rows,
cols,
schemas,
lengths: data_lengths.into_lengths(),
precision,
database: None,
table: None,
fields: fields.iter().map(|s| s.name().to_string()).collect(),
columns,
group_id: 0,
// raw_fields: Vec::new(),
}
}
sourcepub fn escaped_name(&self) -> String
pub fn escaped_name(&self) -> String
Escaped file name
Examples found in repository?
src/common/raw/meta.rs (line 222)
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("CREATE TABLE IF NOT EXISTS ")?;
match self {
MetaCreate::Super {
table_name,
columns,
tags,
} => {
debug_assert!(columns.len() > 0, "{:?}", self);
debug_assert!(tags.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
f.write_str(" TAGS(")?;
f.write_str(&tags.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
MetaCreate::Child {
table_name,
using,
tags,
tag_num,
} => {
if tags.len() > 0 {
f.write_fmt(format_args!(
"`{}` USING `{}` ({}) TAGS({})",
table_name,
using,
tags.iter().map(|t| t.field.escaped_name()).join(", "),
tags.iter()
.map(|t| {
match t.field.ty() {
Ty::Json => format!("'{}'", t.value.as_str().unwrap()),
Ty::VarChar | Ty::NChar => {
format!("{}", t.value.as_str().unwrap())
}
_ => format!("{}", t.value),
}
})
.join(", ")
))?;
} else {
f.write_fmt(format_args!(
"`{}` USING `{}` TAGS({})",
table_name,
using,
std::iter::repeat("NULL").take(tag_num.unwrap()).join(",")
))?;
}
}
MetaCreate::Normal {
table_name,
columns,
} => {
debug_assert!(columns.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
}
Ok(())
}
sourcepub const fn ty(&self) -> Ty
pub const fn ty(&self) -> Ty
Data type of the field.
Examples found in repository?
More examples
src/common/field.rs (line 50)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
fn from(value: &Field) -> Self {
// let name = value.name().into_c_str().into_owned();
let name = value.name().as_bytes();
let mut field = c_field_t {
name: [0; 65],
type_: value.ty() as _,
bytes: value.bytes() as _,
};
unsafe {
std::ptr::copy_nonoverlapping(name.as_ptr(), field.name.as_mut_ptr() as _, name.len());
}
field
}
}
impl Inlinable for Field {
fn write_inlined<W: std::io::Write>(&self, wtr: &mut W) -> std::io::Result<usize> {
let mut l = wtr.write_u8_le(self.ty as u8)?;
l += wtr.write_u32_le(self.bytes)?;
l += wtr.write_inlined_str::<2>(&self.name)?;
Ok(l)
}
fn read_inlined<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let ty = Ty::from(reader.read_u8()?);
let bytes = reader.read_u32()?;
let name = reader.read_inlined_str::<2>()?;
Ok(Self { name, ty, bytes })
}
}
impl Field {
pub const fn empty() -> Self {
Self {
name: String::new(),
ty: Ty::Null,
bytes: 0,
}
}
pub fn new(name: impl Into<String>, ty: Ty, bytes: u32) -> Self {
let name = name.into();
Self { name, ty, bytes }
}
/// Field name.
pub fn name(&self) -> &str {
&self.name
}
/// Escaped file name
pub fn escaped_name(&self) -> String {
format!("`{}`", self.name())
}
/// Data type of the field.
pub const fn ty(&self) -> Ty {
self.ty
}
/// Preset length of variable length data type.
///
/// It's the byte-width in other types.
pub const fn bytes(&self) -> u32 {
self.bytes
}
pub fn to_c_field(&self) -> c_field_t {
self.into()
}
/// Represent the data type in sql.
///
/// For example: "INT", "VARCHAR(100)".
pub fn sql_repr(&self) -> String {
let ty = self.ty();
if ty.is_var_type() {
format!("`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
format!("`{}` {}", self.name(), ty.name())
}
}
}
impl Display for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ty = self.ty();
if ty.is_var_type() {
write!(f, "`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
write!(f, "`{}` {}", self.name(), ty.name())
}
}
src/common/raw/meta.rs (line 225)
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("CREATE TABLE IF NOT EXISTS ")?;
match self {
MetaCreate::Super {
table_name,
columns,
tags,
} => {
debug_assert!(columns.len() > 0, "{:?}", self);
debug_assert!(tags.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
f.write_str(" TAGS(")?;
f.write_str(&tags.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
MetaCreate::Child {
table_name,
using,
tags,
tag_num,
} => {
if tags.len() > 0 {
f.write_fmt(format_args!(
"`{}` USING `{}` ({}) TAGS({})",
table_name,
using,
tags.iter().map(|t| t.field.escaped_name()).join(", "),
tags.iter()
.map(|t| {
match t.field.ty() {
Ty::Json => format!("'{}'", t.value.as_str().unwrap()),
Ty::VarChar | Ty::NChar => {
format!("{}", t.value.as_str().unwrap())
}
_ => format!("{}", t.value),
}
})
.join(", ")
))?;
} else {
f.write_fmt(format_args!(
"`{}` USING `{}` TAGS({})",
table_name,
using,
std::iter::repeat("NULL").take(tag_num.unwrap()).join(",")
))?;
}
}
MetaCreate::Normal {
table_name,
columns,
} => {
debug_assert!(columns.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
}
Ok(())
}
src/common/raw/mod.rs (line 284)
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
pub fn parse_from_raw_block_v2(
bytes: impl Into<Bytes>,
fields: &[Field],
lengths: &[u32],
rows: usize,
precision: Precision,
) -> Self {
use bytes::BufMut;
debug_assert_eq!(fields.len(), lengths.len());
const fn bool_is_null(v: *const bool) -> bool {
unsafe { *(v as *const u8) == 0x02 }
}
const fn tiny_int_is_null(v: *const i8) -> bool {
unsafe { *(v as *const u8) == 0x80 }
}
const fn small_int_is_null(v: *const i16) -> bool {
unsafe { *(v as *const u16) == 0x8000 }
}
const fn int_is_null(v: *const i32) -> bool {
unsafe { *(v as *const u32) == 0x80000000 }
}
const fn big_int_is_null(v: *const i64) -> bool {
unsafe { *(v as *const u64) == 0x8000000000000000 }
}
const fn u_tiny_int_is_null(v: *const u8) -> bool {
unsafe { *(v as *const u8) == 0xFF }
}
const fn u_small_int_is_null(v: *const u16) -> bool {
unsafe { *(v as *const u16) == 0xFFFF }
}
const fn u_int_is_null(v: *const u32) -> bool {
unsafe { *(v as *const u32) == 0xFFFFFFFF }
}
const fn u_big_int_is_null(v: *const u64) -> bool {
unsafe { *(v as *const u64) == 0xFFFFFFFFFFFFFFFF }
}
const fn float_is_null(v: *const f32) -> bool {
unsafe { *(v as *const u32) == 0x7FF00000 }
}
const fn double_is_null(v: *const f64) -> bool {
unsafe { *(v as *const u64) == 0x7FFFFF0000000000 }
}
// const BOOL_NULL: u8 = 0x2;
// const TINY_INT_NULL: i8 = i8::MIN;
// const SMALL_INT_NULL: i16 = i16::MIN;
// const INT_NULL: i32 = i32::MIN;
// const BIG_INT_NULL: i64 = i64::MIN;
// const FLOAT_NULL: f32 = 0x7FF00000i32 as f32;
// const DOUBLE_NULL: f64 = 0x7FFFFF0000000000i64 as f64;
// const U_TINY_INT_NULL: u8 = u8::MAX;
// const U_SMALL_INT_NULL: u16 = u16::MAX;
// const U_INT_NULL: u32 = u32::MAX;
// const U_BIG_INT_NULL: u64 = u64::MAX;
let layout = Arc::new(RefCell::new(
Layout::INLINE_DEFAULT.with_schema_changed().into(),
));
let bytes = bytes.into();
let cols = fields.len();
let mut schemas_bytes =
bytes::BytesMut::with_capacity(rows * std::mem::size_of::<ColSchema>());
fields
.iter()
.for_each(|f| schemas_bytes.put(f.to_column_schema().as_bytes()));
let schemas = Schemas::from(schemas_bytes);
let mut data_lengths = LengthsMut::new(cols);
let mut columns = Vec::new();
let mut offset = 0;
for (i, (field, length)) in fields.into_iter().zip(&*lengths).enumerate() {
macro_rules! _primitive_view {
($ty:ident, $prim:ty) => {{
debug_assert_eq!(field.bytes(), *length);
// column start
let start = offset;
// column end
offset += rows * std::mem::size_of::<$prim>() as usize;
// byte slice from start to end: `[start, end)`.
let data = bytes.slice(start..offset);
// value as target type
let value_slice = unsafe {
std::slice::from_raw_parts(
transmute::<*const u8, *const $prim>(data.as_ptr()),
rows,
)
};
// Set data lengths for v3-compatible block.
data_lengths[i] = data.len() as u32;
// generate nulls bitmap.
let nulls = NullsMut::from_bools(
value_slice
.iter()
.map(|v| paste::paste!{ [<$ty:snake _is_null>](v as _) })
// .map(|b| *b as u64 == paste::paste! { [<$ty:snake:upper _NULL>] }),
)
.into_nulls();
// build column view
let column = paste::paste! { ColumnView::$ty([<$ty View>] { nulls, data }) };
columns.push(column);
}};
}
match field.ty() {
Ty::Null => unreachable!(),
// Signed integers columns.
Ty::Bool => _primitive_view!(Bool, bool),
Ty::TinyInt => _primitive_view!(TinyInt, i8),
Ty::SmallInt => _primitive_view!(SmallInt, i16),
Ty::Int => _primitive_view!(Int, i32),
Ty::BigInt => _primitive_view!(BigInt, i64),
// Unsigned integers columns.
Ty::UTinyInt => _primitive_view!(UTinyInt, u8),
Ty::USmallInt => _primitive_view!(USmallInt, u16),
Ty::UInt => _primitive_view!(UInt, u32),
Ty::UBigInt => _primitive_view!(UBigInt, u64),
// Float columns.
Ty::Float => _primitive_view!(Float, f32),
Ty::Double => _primitive_view!(Double, f64),
Ty::VarChar => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 1 && *ptr.offset(2) == 0xFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::VarChar(VarCharView { offsets, data }));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::Timestamp => {
// column start
let start = offset;
// column end
offset += rows * std::mem::size_of::<i64>() as usize;
// byte slice from start to end: `[start, end)`.
let data = bytes.slice(start..offset);
// value as target type
let value_slice = unsafe {
std::slice::from_raw_parts(
transmute::<*const u8, *const i64>(data.as_ptr()),
rows,
)
};
// Set data lengths for v3-compatible block.
data_lengths[i] = data.len() as u32;
// generate nulls bitmap.
let nulls =
NullsMut::from_bools(value_slice.iter().map(|b| big_int_is_null(b as _)))
.into_nulls();
// build column view
let column = ColumnView::Timestamp(TimestampView {
nulls,
data,
precision,
});
columns.push(column);
}
Ty::NChar => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 4 && *(ptr.offset(2) as *const u32) == 0xFFFFFFFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::NChar(NCharView {
offsets,
data,
is_chars: UnsafeCell::new(false),
version: Version::V2,
layout: layout.clone(),
}));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::Json => {
let start = offset;
offset += *length as usize * rows;
let data = bytes.slice(start..offset);
let data_ptr = data.as_ptr();
let offsets = Offsets::from_offsets((0..rows).into_iter().map(|row| unsafe {
let offset = row as i32 * *length as i32;
let ptr = data_ptr.offset(offset as isize);
let len = *transmute::<*const u8, *const u16>(ptr);
if len == 4 && *(ptr.offset(2) as *const u32) == 0xFFFFFFFF {
-1
} else {
offset
}
}));
columns.push(ColumnView::Json(JsonView { offsets, data }));
data_lengths[i] = *length as u32 * rows as u32;
}
Ty::VarBinary => todo!(),
Ty::Decimal => todo!(),
Ty::Blob => todo!(),
Ty::MediumBlob => todo!(),
}
}
Self {
layout,
version: Version::V2,
data: Cell::new(bytes),
rows,
cols,
schemas,
lengths: data_lengths.into_lengths(),
precision,
database: None,
table: None,
fields: fields.iter().map(|s| s.name().to_string()).collect(),
columns,
group_id: 0,
// raw_fields: Vec::new(),
}
}
sourcepub const fn bytes(&self) -> u32
pub const fn bytes(&self) -> u32
Preset length of variable length data type.
It’s the byte-width in other types.
Examples found in repository?
More examples
src/common/field.rs (line 51)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
fn from(value: &Field) -> Self {
// let name = value.name().into_c_str().into_owned();
let name = value.name().as_bytes();
let mut field = c_field_t {
name: [0; 65],
type_: value.ty() as _,
bytes: value.bytes() as _,
};
unsafe {
std::ptr::copy_nonoverlapping(name.as_ptr(), field.name.as_mut_ptr() as _, name.len());
}
field
}
}
impl Inlinable for Field {
fn write_inlined<W: std::io::Write>(&self, wtr: &mut W) -> std::io::Result<usize> {
let mut l = wtr.write_u8_le(self.ty as u8)?;
l += wtr.write_u32_le(self.bytes)?;
l += wtr.write_inlined_str::<2>(&self.name)?;
Ok(l)
}
fn read_inlined<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let ty = Ty::from(reader.read_u8()?);
let bytes = reader.read_u32()?;
let name = reader.read_inlined_str::<2>()?;
Ok(Self { name, ty, bytes })
}
}
impl Field {
pub const fn empty() -> Self {
Self {
name: String::new(),
ty: Ty::Null,
bytes: 0,
}
}
pub fn new(name: impl Into<String>, ty: Ty, bytes: u32) -> Self {
let name = name.into();
Self { name, ty, bytes }
}
/// Field name.
pub fn name(&self) -> &str {
&self.name
}
/// Escaped file name
pub fn escaped_name(&self) -> String {
format!("`{}`", self.name())
}
/// Data type of the field.
pub const fn ty(&self) -> Ty {
self.ty
}
/// Preset length of variable length data type.
///
/// It's the byte-width in other types.
pub const fn bytes(&self) -> u32 {
self.bytes
}
pub fn to_c_field(&self) -> c_field_t {
self.into()
}
/// Represent the data type in sql.
///
/// For example: "INT", "VARCHAR(100)".
pub fn sql_repr(&self) -> String {
let ty = self.ty();
if ty.is_var_type() {
format!("`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
format!("`{}` {}", self.name(), ty.name())
}
}
}
impl Display for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ty = self.ty();
if ty.is_var_type() {
write!(f, "`{}` {}({})", self.name(), ty.name(), self.bytes())
} else {
write!(f, "`{}` {}", self.name(), ty.name())
}
}
pub fn to_c_field(&self) -> c_field_t
sourcepub fn sql_repr(&self) -> String
pub fn sql_repr(&self) -> String
Represent the data type in sql.
For example: “INT”, “VARCHAR(100)”.
Examples found in repository?
src/common/raw/meta.rs (line 204)
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("CREATE TABLE IF NOT EXISTS ")?;
match self {
MetaCreate::Super {
table_name,
columns,
tags,
} => {
debug_assert!(columns.len() > 0, "{:?}", self);
debug_assert!(tags.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
f.write_str(" TAGS(")?;
f.write_str(&tags.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
MetaCreate::Child {
table_name,
using,
tags,
tag_num,
} => {
if tags.len() > 0 {
f.write_fmt(format_args!(
"`{}` USING `{}` ({}) TAGS({})",
table_name,
using,
tags.iter().map(|t| t.field.escaped_name()).join(", "),
tags.iter()
.map(|t| {
match t.field.ty() {
Ty::Json => format!("'{}'", t.value.as_str().unwrap()),
Ty::VarChar | Ty::NChar => {
format!("{}", t.value.as_str().unwrap())
}
_ => format!("{}", t.value),
}
})
.join(", ")
))?;
} else {
f.write_fmt(format_args!(
"`{}` USING `{}` TAGS({})",
table_name,
using,
std::iter::repeat("NULL").take(tag_num.unwrap()).join(",")
))?;
}
}
MetaCreate::Normal {
table_name,
columns,
} => {
debug_assert!(columns.len() > 0);
f.write_fmt(format_args!("`{}`", table_name))?;
f.write_char('(')?;
f.write_str(&columns.iter().map(|f| f.sql_repr()).join(", "))?;
f.write_char(')')?;
}
}
Ok(())
}
}
#[test]
fn test_meta_create_to_sql() {
// let sql = MetaCreate {
// table_name: "abc".to_string(),
// table_type: TableType::Super,
// using: None,
// columns: vec![
// Field::new("ts", Ty::Timestamp, 0),
// Field::new("location", Ty::VarChar, 16),
// ],
// tags: vec![],
// }
// .to_string();
// assert_eq!(
// sql,
// "CREATE TABLE IF NOT EXISTS `abc`(`ts` TIMESTAMP, `location` BINARY(16))"
// );
}
#[derive(Debug, Deserialize_repr, Serialize_repr, Clone, Copy)]
#[repr(u8)]
pub enum AlterType {
AddTag = 1,
DropTag = 2,
RenameTag = 3,
SetTagValue = 4,
AddColumn = 5,
DropColumn = 6,
ModifyColumnLength,
ModifyTagLength,
ModifyTableOption,
RenameColumn,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
// #[serde(tag = "tableType")]
#[serde(rename_all = "camelCase")]
pub struct MetaAlter {
pub table_name: String,
pub alter_type: AlterType,
#[serde(flatten, with = "ColField")]
pub field: Field,
pub col_new_name: Option<String>,
pub col_value: Option<String>,
pub col_value_null: Option<bool>,
}
impl Display for MetaAlter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.alter_type {
AlterType::AddTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` ADD TAG {}",
self.table_name,
self.field.sql_repr()
)),
AlterType::DropTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` DROP TAG `{}`",
self.table_name,
self.field.name()
)),
AlterType::RenameTag => f.write_fmt(format_args!(
"ALTER TABLE `{}` RENAME TAG `{}` `{}`",
self.table_name,
self.field.name(),
self.col_new_name.as_ref().unwrap()
)),
AlterType::SetTagValue => {
f.write_fmt(format_args!(
"ALTER TABLE `{}` SET TAG `{}` ",
self.table_name,
self.field.name()
))?;
if self.col_value_null.unwrap_or(false) {
f.write_str("NULL")
} else if self.field.ty.is_var_type() {
f.write_fmt(format_args!("'{}'", self.col_value.as_ref().unwrap()))
} else {
f.write_fmt(format_args!("{}", self.col_value.as_ref().unwrap()))
}
}
AlterType::AddColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` ADD COLUMN {}",
self.table_name,
self.field.sql_repr()
)),
AlterType::DropColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` DROP COLUMN `{}`",
self.table_name,
self.field.name()
)),
AlterType::ModifyColumnLength => f.write_fmt(format_args!(
"ALTER TABLE `{}` MODIFY COLUMN {}",
self.table_name,
self.field.sql_repr(),
)),
AlterType::ModifyTagLength => f.write_fmt(format_args!(
"ALTER TABLE `{}` MODIFY TAG {}",
self.table_name,
self.field.sql_repr(),
)),
AlterType::ModifyTableOption => todo!(),
AlterType::RenameColumn => f.write_fmt(format_args!(
"ALTER TABLE `{}` RENAME COLUMN `{}` `{}`",
self.table_name,
self.field.name(),
self.col_new_name.as_ref().unwrap()
)),
}
}
Trait Implementations§
source§impl<'de> Deserialize<'de> for Field
impl<'de> Deserialize<'de> for Field
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
source§impl Inlinable for Field
impl Inlinable for Field
source§fn write_inlined<W: Write>(&self, wtr: &mut W) -> Result<usize>
fn write_inlined<W: Write>(&self, wtr: &mut W) -> Result<usize>
Write inlined bytes to a writer.
fn read_optional_inlined<R: Read>(reader: &mut R) -> Result<Option<Self>>where
Self: Sized,
source§fn write_inlined_with<W: Write>(
&self,
wtr: &mut W,
_opts: InlineOpts
) -> Result<usize>
fn write_inlined_with<W: Write>(
&self,
wtr: &mut W,
_opts: InlineOpts
) -> Result<usize>
Write inlined bytes with specific options
source§fn printable_inlined(&self) -> String
fn printable_inlined(&self) -> String
Get inlined bytes as printable string, all the bytes will displayed with escaped ascii code.
source§impl PartialEq<Field> for Field
impl PartialEq<Field> for Field
impl Eq for Field
impl StructuralEq for Field
impl StructuralPartialEq for Field
Auto Trait Implementations§
impl RefUnwindSafe for Field
impl Send for Field
impl Sync for Field
impl Unpin for Field
impl UnwindSafe for Field
Blanket Implementations§
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
Causes
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
Causes
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
Causes
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
Causes
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
Causes
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
Causes
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
Causes
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
Causes
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
Formats each item in a sequence. Read more
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Pipes by value. This is generally the method you want to use. Read more
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
Borrows
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
Mutably borrows
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
Borrows
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
Mutably borrows
self
, then passes self.as_mut()
into the pipe
function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Immutable access to the
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Mutable access to the
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Immutable access to the
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Mutable access to the
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Immutable access to the
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Mutable access to the
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
Calls
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
Calls
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Calls
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Calls
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Calls
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Calls
.tap_ref_mut()
only in debug builds, and is erased in release
builds.