
The major change in schemars 1.0 is that now schemas are represented as plain json values instead of specialized datatypes. This allows for more concise construction and manipulation. This change also improves how settings schemas are generated. Each top level settings type was being generated as a full root schema including the definitions it references, and then these were merged. This meant generating all shared definitions multiple times, and might have bugs in cases where there are two types with the same names. Now instead the schemar generator's `definitions` are built up as they normally are and the `Settings` trait no longer has a special `json_schema` method. To handle types that have schema that vary at runtime (`FontFamilyName`, `ThemeName`, etc), values of `ParameterizedJsonSchema` are collected by `inventory`, and the schema definitions for these types are replaced. To help check that this doesn't break anything, I tried to minimize the overall [schema diff](https://gist.github.com/mgsloan/1de549def20399d6f37943a3c1583ee7) with some patches to make the order more consistent + schemas also sorted with `jq -S .`. A skim of the diff shows that the diffs come from: * `enum: ["value"]` turning into `const: "value"` * Differences in handling of newlines for "description" * Schemas for generic types no longer including the parameter name, now all disambiguation is with numeric suffixes * Enums now using `oneOf` instead of `anyOf`. Release Notes: - N/A
140 lines
3.3 KiB
Rust
140 lines
3.3 KiB
Rust
use derive_more::{Deref, DerefMut};
|
|
|
|
use schemars::JsonSchema;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{
|
|
borrow::{Borrow, Cow},
|
|
sync::Arc,
|
|
};
|
|
use util::arc_cow::ArcCow;
|
|
|
|
/// A shared string is an immutable string that can be cheaply cloned in GPUI
|
|
/// tasks. Essentially an abstraction over an `Arc<str>` and `&'static str`,
|
|
#[derive(Deref, DerefMut, Eq, PartialEq, PartialOrd, Ord, Hash, Clone)]
|
|
pub struct SharedString(ArcCow<'static, str>);
|
|
|
|
impl SharedString {
|
|
/// Creates a static [`SharedString`] from a `&'static str`.
|
|
pub const fn new_static(str: &'static str) -> Self {
|
|
Self(ArcCow::Borrowed(str))
|
|
}
|
|
|
|
/// Creates a [`SharedString`] from anything that can become an `Arc<str>`
|
|
pub fn new(str: impl Into<Arc<str>>) -> Self {
|
|
SharedString(ArcCow::Owned(str.into()))
|
|
}
|
|
}
|
|
|
|
impl JsonSchema for SharedString {
|
|
fn inline_schema() -> bool {
|
|
String::inline_schema()
|
|
}
|
|
|
|
fn schema_name() -> Cow<'static, str> {
|
|
String::schema_name()
|
|
}
|
|
|
|
fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
|
|
String::json_schema(generator)
|
|
}
|
|
}
|
|
|
|
impl Default for SharedString {
|
|
fn default() -> Self {
|
|
Self(ArcCow::Owned(Arc::default()))
|
|
}
|
|
}
|
|
|
|
impl AsRef<str> for SharedString {
|
|
fn as_ref(&self) -> &str {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl Borrow<str> for SharedString {
|
|
fn borrow(&self) -> &str {
|
|
self.as_ref()
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for SharedString {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
self.0.fmt(f)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for SharedString {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.0.as_ref())
|
|
}
|
|
}
|
|
|
|
impl PartialEq<String> for SharedString {
|
|
fn eq(&self, other: &String) -> bool {
|
|
self.as_ref() == other
|
|
}
|
|
}
|
|
|
|
impl PartialEq<SharedString> for String {
|
|
fn eq(&self, other: &SharedString) -> bool {
|
|
self == other.as_ref()
|
|
}
|
|
}
|
|
|
|
impl PartialEq<str> for SharedString {
|
|
fn eq(&self, other: &str) -> bool {
|
|
self.as_ref() == other
|
|
}
|
|
}
|
|
|
|
impl<'a> PartialEq<&'a str> for SharedString {
|
|
fn eq(&self, other: &&'a str) -> bool {
|
|
self.as_ref() == *other
|
|
}
|
|
}
|
|
|
|
impl From<&SharedString> for SharedString {
|
|
fn from(value: &SharedString) -> Self {
|
|
value.clone()
|
|
}
|
|
}
|
|
|
|
impl From<SharedString> for Arc<str> {
|
|
fn from(val: SharedString) -> Self {
|
|
match val.0 {
|
|
ArcCow::Borrowed(borrowed) => Arc::from(borrowed),
|
|
ArcCow::Owned(owned) => owned.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
|
|
fn from(value: T) -> Self {
|
|
Self(value.into())
|
|
}
|
|
}
|
|
|
|
impl From<SharedString> for String {
|
|
fn from(val: SharedString) -> Self {
|
|
val.0.to_string()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SharedString {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
serializer.serialize_str(self.as_ref())
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for SharedString {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: serde::Deserializer<'de>,
|
|
{
|
|
let s = String::deserialize(deserializer)?;
|
|
Ok(SharedString::from(s))
|
|
}
|
|
}
|