mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
♻️ Make SerializableResult to depend on From traits
This commit is contained in:
@@ -303,7 +303,7 @@ pub extern "C" fn set_focus_mode() {
|
|||||||
|
|
||||||
let entries: Vec<Uuid> = bytes
|
let entries: Vec<Uuid> = bytes
|
||||||
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
||||||
.map(|data| Uuid::from_bytes(data.try_into().unwrap()))
|
.map(|data| Uuid::try_from(data).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
with_state_mut!(state, {
|
with_state_mut!(state, {
|
||||||
@@ -523,7 +523,7 @@ pub extern "C" fn set_children() {
|
|||||||
|
|
||||||
let entries: Vec<Uuid> = bytes
|
let entries: Vec<Uuid> = bytes
|
||||||
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
||||||
.map(|data| Uuid::from_bytes(data.try_into().unwrap()))
|
.map(|data| Uuid::try_from(data).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
set_children_set(entries);
|
set_children_set(entries);
|
||||||
@@ -679,7 +679,7 @@ pub extern "C" fn propagate_modifiers(pixel_precision: bool) -> *mut u8 {
|
|||||||
|
|
||||||
let entries: Vec<_> = bytes
|
let entries: Vec<_> = bytes
|
||||||
.chunks(size_of::<<TransformEntry as SerializableResult>::BytesType>())
|
.chunks(size_of::<<TransformEntry as SerializableResult>::BytesType>())
|
||||||
.map(|data| TransformEntry::from_bytes(data.try_into().unwrap()))
|
.map(|data| TransformEntry::try_from(data).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
with_state!(state, {
|
with_state!(state, {
|
||||||
@@ -694,7 +694,7 @@ pub extern "C" fn set_modifiers() {
|
|||||||
|
|
||||||
let entries: Vec<_> = bytes
|
let entries: Vec<_> = bytes
|
||||||
.chunks(size_of::<<TransformEntry as SerializableResult>::BytesType>())
|
.chunks(size_of::<<TransformEntry as SerializableResult>::BytesType>())
|
||||||
.map(|data| TransformEntry::from_bytes(data.try_into().unwrap()))
|
.map(|data| TransformEntry::try_from(data).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut modifiers = HashMap::new();
|
let mut modifiers = HashMap::new();
|
||||||
|
|||||||
@@ -57,10 +57,8 @@ pub fn bytes_or_empty() -> Vec<u8> {
|
|||||||
guard.take().unwrap_or_default()
|
guard.take().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SerializableResult {
|
pub trait SerializableResult: From<Self::BytesType> + Into<Self::BytesType> {
|
||||||
type BytesType;
|
type BytesType;
|
||||||
fn from_bytes(bytes: Self::BytesType) -> Self;
|
|
||||||
fn as_bytes(&self) -> Self::BytesType;
|
|
||||||
fn clone_to_slice(&self, slice: &mut [u8]);
|
fn clone_to_slice(&self, slice: &mut [u8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ pub fn propagate_modifiers(
|
|||||||
if math::identitish(&entry.transform) {
|
if math::identitish(&entry.transform) {
|
||||||
Modifier::Reflow(entry.id)
|
Modifier::Reflow(entry.id)
|
||||||
} else {
|
} else {
|
||||||
Modifier::Transform(entry.clone())
|
Modifier::Transform(*entry)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -1053,7 +1053,7 @@ impl TextSpan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct PositionData {
|
pub struct PositionData {
|
||||||
pub paragraph: u32,
|
pub paragraph: u32,
|
||||||
pub span: u32,
|
pub span: u32,
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ impl Modifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
pub enum TransformEntrySource {
|
pub enum TransformEntrySource {
|
||||||
Input,
|
Input,
|
||||||
Propagate,
|
Propagate,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransformEntry {
|
pub struct TransformEntry {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
@@ -65,10 +65,8 @@ impl TransformEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializableResult for TransformEntry {
|
impl From<[u8; 40]> for TransformEntry {
|
||||||
type BytesType = [u8; 40];
|
fn from(bytes: [u8; 40]) -> Self {
|
||||||
|
|
||||||
fn from_bytes(bytes: Self::BytesType) -> Self {
|
|
||||||
let id = uuid_from_u32_quartet(
|
let id = uuid_from_u32_quartet(
|
||||||
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
|
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
|
||||||
u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
|
u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
|
||||||
@@ -89,29 +87,46 @@ impl SerializableResult for TransformEntry {
|
|||||||
);
|
);
|
||||||
TransformEntry::from_input(id, transform)
|
TransformEntry::from_input(id, transform)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn as_bytes(&self) -> Self::BytesType {
|
impl TryFrom<&[u8]> for TransformEntry {
|
||||||
let mut result: Self::BytesType = [0; 40];
|
type Error = String;
|
||||||
let (a, b, c, d) = uuid_to_u32_quartet(&self.id);
|
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
|
||||||
|
let bytes: [u8; 40] = bytes
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| "Invalid transform entry bytes".to_string())?;
|
||||||
|
Ok(TransformEntry::from(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TransformEntry> for [u8; 40] {
|
||||||
|
fn from(value: TransformEntry) -> Self {
|
||||||
|
let mut result = [0; 40];
|
||||||
|
let (a, b, c, d) = uuid_to_u32_quartet(&value.id);
|
||||||
result[0..4].clone_from_slice(&a.to_le_bytes());
|
result[0..4].clone_from_slice(&a.to_le_bytes());
|
||||||
result[4..8].clone_from_slice(&b.to_le_bytes());
|
result[4..8].clone_from_slice(&b.to_le_bytes());
|
||||||
result[8..12].clone_from_slice(&c.to_le_bytes());
|
result[8..12].clone_from_slice(&c.to_le_bytes());
|
||||||
result[12..16].clone_from_slice(&d.to_le_bytes());
|
result[12..16].clone_from_slice(&d.to_le_bytes());
|
||||||
|
|
||||||
result[16..20].clone_from_slice(&self.transform[0].to_le_bytes());
|
result[16..20].clone_from_slice(&value.transform[0].to_le_bytes());
|
||||||
result[20..24].clone_from_slice(&self.transform[3].to_le_bytes());
|
result[20..24].clone_from_slice(&value.transform[3].to_le_bytes());
|
||||||
result[24..28].clone_from_slice(&self.transform[1].to_le_bytes());
|
result[24..28].clone_from_slice(&value.transform[1].to_le_bytes());
|
||||||
result[28..32].clone_from_slice(&self.transform[4].to_le_bytes());
|
result[28..32].clone_from_slice(&value.transform[4].to_le_bytes());
|
||||||
result[32..36].clone_from_slice(&self.transform[2].to_le_bytes());
|
result[32..36].clone_from_slice(&value.transform[2].to_le_bytes());
|
||||||
result[36..40].clone_from_slice(&self.transform[5].to_le_bytes());
|
result[36..40].clone_from_slice(&value.transform[5].to_le_bytes());
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerializableResult for TransformEntry {
|
||||||
|
type BytesType = [u8; 40];
|
||||||
|
|
||||||
// The generic trait doesn't know the size of the array. This is why the
|
// The generic trait doesn't know the size of the array. This is why the
|
||||||
// clone needs to be here even if it could be generic.
|
// clone needs to be here even if it could be generic.
|
||||||
fn clone_to_slice(&self, slice: &mut [u8]) {
|
fn clone_to_slice(&self, slice: &mut [u8]) {
|
||||||
slice.clone_from_slice(&self.as_bytes());
|
let bytes = Self::BytesType::from(*self);
|
||||||
|
slice.clone_from_slice(&bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,8 +213,8 @@ mod tests {
|
|||||||
Matrix::new_all(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 0.0, 0.0, 1.0),
|
Matrix::new_all(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 0.0, 0.0, 1.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let bytes = entry.as_bytes();
|
let bytes: [u8; 40] = entry.into();
|
||||||
|
|
||||||
assert_eq!(entry, TransformEntry::from_bytes(bytes));
|
assert_eq!(entry, TransformEntry::from(bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,8 @@ impl fmt::Display for Uuid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializableResult for Uuid {
|
impl From<[u8; 16]> for Uuid {
|
||||||
type BytesType = [u8; 16];
|
fn from(bytes: [u8; 16]) -> Self {
|
||||||
|
|
||||||
fn from_bytes(bytes: Self::BytesType) -> Self {
|
|
||||||
Self(*uuid_from_u32_quartet(
|
Self(*uuid_from_u32_quartet(
|
||||||
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
|
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
|
||||||
u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
|
u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
|
||||||
@@ -60,10 +58,22 @@ impl SerializableResult for Uuid {
|
|||||||
u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
|
u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn as_bytes(&self) -> Self::BytesType {
|
impl TryFrom<&[u8]> for Uuid {
|
||||||
let mut result: Self::BytesType = [0; 16];
|
type Error = String;
|
||||||
let (a, b, c, d) = uuid_to_u32_quartet(self);
|
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
|
||||||
|
let bytes: [u8; 16] = bytes
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| "Invalid UUID bytes".to_string())?;
|
||||||
|
Ok(Self::from(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Uuid> for [u8; 16] {
|
||||||
|
fn from(value: Uuid) -> Self {
|
||||||
|
let mut result = [0; 16];
|
||||||
|
let (a, b, c, d) = uuid_to_u32_quartet(&value);
|
||||||
result[0..4].clone_from_slice(&a.to_le_bytes());
|
result[0..4].clone_from_slice(&a.to_le_bytes());
|
||||||
result[4..8].clone_from_slice(&b.to_le_bytes());
|
result[4..8].clone_from_slice(&b.to_le_bytes());
|
||||||
result[8..12].clone_from_slice(&c.to_le_bytes());
|
result[8..12].clone_from_slice(&c.to_le_bytes());
|
||||||
@@ -71,10 +81,15 @@ impl SerializableResult for Uuid {
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerializableResult for Uuid {
|
||||||
|
type BytesType = [u8; 16];
|
||||||
|
|
||||||
// The generic trait doesn't know the size of the array. This is why the
|
// The generic trait doesn't know the size of the array. This is why the
|
||||||
// clone needs to be here even if it could be generic.
|
// clone needs to be here even if it could be generic.
|
||||||
fn clone_to_slice(&self, slice: &mut [u8]) {
|
fn clone_to_slice(&self, slice: &mut [u8]) {
|
||||||
slice.clone_from_slice(&self.as_bytes());
|
let bytes = Self::BytesType::from(*self);
|
||||||
|
slice.clone_from_slice(&bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::mem::SerializableResult;
|
// use crate::mem::SerializableResult;
|
||||||
use crate::uuid::Uuid;
|
use crate::uuid::Uuid;
|
||||||
use crate::with_state_mut;
|
use crate::with_state_mut;
|
||||||
use crate::STATE;
|
use crate::STATE;
|
||||||
@@ -48,8 +48,8 @@ pub struct ShapeImageIds {
|
|||||||
|
|
||||||
impl From<[u8; IMAGE_IDS_SIZE]> for ShapeImageIds {
|
impl From<[u8; IMAGE_IDS_SIZE]> for ShapeImageIds {
|
||||||
fn from(bytes: [u8; IMAGE_IDS_SIZE]) -> Self {
|
fn from(bytes: [u8; IMAGE_IDS_SIZE]) -> Self {
|
||||||
let shape_id = Uuid::from_bytes(bytes[0..16].try_into().unwrap());
|
let shape_id = Uuid::try_from(&bytes[0..16]).unwrap();
|
||||||
let image_id = Uuid::from_bytes(bytes[16..32].try_into().unwrap());
|
let image_id = Uuid::try_from(&bytes[16..32]).unwrap();
|
||||||
ShapeImageIds { shape_id, image_id }
|
ShapeImageIds { shape_id, image_id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ pub extern "C" fn store_image() {
|
|||||||
/// Stores an image from an existing WebGL texture, avoiding re-decoding
|
/// Stores an image from an existing WebGL texture, avoiding re-decoding
|
||||||
/// Expected memory layout:
|
/// Expected memory layout:
|
||||||
/// - bytes 0-15: shape UUID
|
/// - bytes 0-15: shape UUID
|
||||||
/// - bytes 16-31: image UUID
|
/// - bytes 16-31: image UUID
|
||||||
/// - bytes 32-35: is_thumbnail flag (u32)
|
/// - bytes 32-35: is_thumbnail flag (u32)
|
||||||
/// - bytes 36-39: GL texture ID (u32)
|
/// - bytes 36-39: GL texture ID (u32)
|
||||||
/// - bytes 40-43: width (i32)
|
/// - bytes 40-43: width (i32)
|
||||||
|
|||||||
@@ -51,25 +51,20 @@ impl TryFrom<&[u8]> for RawSegmentData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RawSegmentData> for [u8; RAW_SEGMENT_DATA_SIZE] {
|
||||||
|
fn from(value: RawSegmentData) -> Self {
|
||||||
|
unsafe { std::mem::transmute(value) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SerializableResult for RawSegmentData {
|
impl SerializableResult for RawSegmentData {
|
||||||
type BytesType = [u8; RAW_SEGMENT_DATA_SIZE];
|
type BytesType = [u8; RAW_SEGMENT_DATA_SIZE];
|
||||||
|
|
||||||
fn from_bytes(bytes: Self::BytesType) -> Self {
|
|
||||||
unsafe { std::mem::transmute(bytes) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_bytes(&self) -> Self::BytesType {
|
|
||||||
let ptr = self as *const RawSegmentData as *const u8;
|
|
||||||
let bytes: &[u8] = unsafe { std::slice::from_raw_parts(ptr, RAW_SEGMENT_DATA_SIZE) };
|
|
||||||
let mut result = [0; RAW_SEGMENT_DATA_SIZE];
|
|
||||||
result.copy_from_slice(bytes);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
// The generic trait doesn't know the size of the array. This is why the
|
// The generic trait doesn't know the size of the array. This is why the
|
||||||
// clone needs to be here even if it could be generic.
|
// clone needs to be here even if it could be generic.
|
||||||
fn clone_to_slice(&self, slice: &mut [u8]) {
|
fn clone_to_slice(&self, slice: &mut [u8]) {
|
||||||
slice.clone_from_slice(&self.as_bytes());
|
let bytes = Self::BytesType::from(*self);
|
||||||
|
slice.clone_from_slice(&bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub extern "C" fn calculate_bool(raw_bool_type: u8) -> *mut u8 {
|
|||||||
|
|
||||||
let entries: Vec<Uuid> = bytes
|
let entries: Vec<Uuid> = bytes
|
||||||
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
.chunks(size_of::<<Uuid as SerializableResult>::BytesType>())
|
||||||
.map(|data| Uuid::from_bytes(data.try_into().unwrap()))
|
.map(|data| Uuid::try_from(data).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
mem::free_bytes();
|
mem::free_bytes();
|
||||||
|
|||||||
@@ -415,24 +415,26 @@ pub extern "C" fn get_caret_position_at(x: f32, y: f32) -> i32 {
|
|||||||
|
|
||||||
const RAW_POSITION_DATA_SIZE: usize = size_of::<shapes::PositionData>();
|
const RAW_POSITION_DATA_SIZE: usize = size_of::<shapes::PositionData>();
|
||||||
|
|
||||||
impl SerializableResult for shapes::PositionData {
|
impl From<[u8; RAW_POSITION_DATA_SIZE]> for shapes::PositionData {
|
||||||
type BytesType = [u8; RAW_POSITION_DATA_SIZE];
|
fn from(bytes: [u8; RAW_POSITION_DATA_SIZE]) -> Self {
|
||||||
|
|
||||||
fn from_bytes(bytes: Self::BytesType) -> Self {
|
|
||||||
unsafe { std::mem::transmute(bytes) }
|
unsafe { std::mem::transmute(bytes) }
|
||||||
}
|
}
|
||||||
fn as_bytes(&self) -> Self::BytesType {
|
}
|
||||||
let ptr = self as *const shapes::PositionData as *const u8;
|
|
||||||
let bytes: &[u8] = unsafe { std::slice::from_raw_parts(ptr, RAW_POSITION_DATA_SIZE) };
|
impl From<shapes::PositionData> for [u8; RAW_POSITION_DATA_SIZE] {
|
||||||
let mut result = [0; RAW_POSITION_DATA_SIZE];
|
fn from(value: shapes::PositionData) -> Self {
|
||||||
result.copy_from_slice(bytes);
|
unsafe { std::mem::transmute(value) }
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerializableResult for shapes::PositionData {
|
||||||
|
type BytesType = [u8; RAW_POSITION_DATA_SIZE];
|
||||||
|
|
||||||
// The generic trait doesn't know the size of the array. This is why the
|
// The generic trait doesn't know the size of the array. This is why the
|
||||||
// clone needs to be here even if it could be generic.
|
// clone needs to be here even if it could be generic.
|
||||||
fn clone_to_slice(&self, slice: &mut [u8]) {
|
fn clone_to_slice(&self, slice: &mut [u8]) {
|
||||||
slice.clone_from_slice(&self.as_bytes());
|
let bytes = Self::BytesType::from(*self);
|
||||||
|
slice.clone_from_slice(&bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user