Repository: GraphiteEditor/Graphite
File: node-graph/gcore/src/types.rs (Rust)

Code before:
		f.write_fmt(format_args!(
			"node({}) → {}",
			[&self.call_argument].into_iter().chain(&self.inputs).map(|input| input.to_string()).collect::<Vec<_>>().join(", "),
			self.return_value
		))
	}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, specta::Type)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ProtoNodeIdentifier {
	pub name: Cow<'static, str>,
}
impl From<String> for ProtoNodeIdentifier {
	fn from(value: String) -> Self {
		Self { name: Cow::Owned(value) }
	}
}

fn migrate_type_descriptor_names<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Cow<'static, str>, D::Error> {
	use serde::Deserialize;

	let name = String::deserialize(deserializer)?;
	let name = match name.as_str() {
		"f32" => "f64".to_string(),
		"graphene_core::transform::Footprint" => "std::option::Option<std::sync::Arc<graphene_core::context::OwnedContextImpl>>".to_string(),
		"graphene_core::graphic_element::GraphicGroup" => "graphene_core::instances::Instances<graphene_core::graphic_element::GraphicGroup>".to_string(),
		"graphene_core::vector::vector_data::VectorData" => "graphene_core::instances::Instances<graphene_core::vector::vector_data::VectorData>".to_string(),
		"graphene_core::raster::image::ImageFrame<Color>"
		| "graphene_core::raster::image::ImageFrame<graphene_core::raster::color::Color>"
		| "graphene_core::instances::Instances<graphene_core::raster::image::ImageFrame<Color>>"
		| "graphene_core::instances::Instances<graphene_core::raster::image::ImageFrame<graphene_core::raster::color::Color>>" => {
			"graphene_core::instances::Instances<graphene_core::raster::image::Image<graphene_core::raster::color::Color>>".to_string()
		}
		_ => name,
	};

	Ok(Cow::Owned(name))
}

#[derive(Clone, Debug, Eq, specta::Type)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TypeDescriptor {
	#[cfg_attr(feature = "serde", serde(skip))]
	#[specta(skip)]
	pub id: Option<TypeId>,
	#[serde(deserialize_with = "migrate_type_descriptor_names")]
	pub name: Cow<'static, str>,
	#[serde(default)]
	pub alias: Option<Cow<'static, str>>,
	#[serde(skip)]

Review comment (suggestion):
I'm unsure whether this will cause breakage or not. While `core` would still compile, `alloc` shouldn't since I removed the `external crate alloc;`. Even if this particular migration code may be fine to be changed, it could indicate trouble with other documents in the wild. At least the demo artworks are unaffected.

Code after:
		f.write_fmt(format_args!(
			"node({}) → {}",
			[&self.call_argument].into_iter().chain(&self.inputs).map(|input| input.to_string()).collect::<Vec<_>>().join(", "),
			self.return_value
		))
	}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, specta::Type)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ProtoNodeIdentifier {
	pub name: Cow<'static, str>,
}
impl From<String> for ProtoNodeIdentifier {
	fn from(value: String) -> Self {
		Self { name: Cow::Owned(value) }
	}
}

fn migrate_type_descriptor_names<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Cow<'static, str>, D::Error> {
	use serde::Deserialize;

	let name = String::deserialize(deserializer)?;
	let name = match name.as_str() {
		"f32" => "f64".to_string(),
		"graphene_core::transform::Footprint" => "core::option::Option<alloc::sync::Arc<graphene_core::context::OwnedContextImpl>>".to_string(),
		"graphene_core::graphic_element::GraphicGroup" => "graphene_core::instances::Instances<graphene_core::graphic_element::GraphicGroup>".to_string(),
		"graphene_core::vector::vector_data::VectorData" => "graphene_core::instances::Instances<graphene_core::vector::vector_data::VectorData>".to_string(),
		"graphene_core::raster::image::ImageFrame<Color>"
		| "graphene_core::raster::image::ImageFrame<graphene_core::raster::color::Color>"
		| "graphene_core::instances::Instances<graphene_core::raster::image::ImageFrame<Color>>"
		| "graphene_core::instances::Instances<graphene_core::raster::image::ImageFrame<graphene_core::raster::color::Color>>" => {
			"graphene_core::instances::Instances<graphene_core::raster::image::Image<graphene_core::raster::color::Color>>".to_string()
		}
		_ => name,
	};

	Ok(Cow::Owned(name))
}

#[derive(Clone, Debug, Eq, specta::Type)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TypeDescriptor {
	#[cfg_attr(feature = "serde", serde(skip))]
	#[specta(skip)]
	pub id: Option<TypeId>,
	#[serde(deserialize_with = "migrate_type_descriptor_names")]
	pub name: Cow<'static, str>,
	#[serde(default)]
	pub alias: Option<Cow<'static, str>>,
	#[serde(skip)]