mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-03-02 05:04:43 +08:00
Serialization refactoring to drop suboject logic
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import GeneralSerializer from "./GeneralSerializer.js"
|
||||
|
||||
/**
|
||||
* @typedef {import("../entity/IEntity").default} IEntity
|
||||
* @typedef {import("../entity/IEntity").AnyValue} AnyValue
|
||||
* @typedef {import("../entity/IEntity").AnyValueConstructor<*>} AnyValueConstructor
|
||||
*/
|
||||
@@ -24,12 +23,12 @@ export default class CustomSerializer extends GeneralSerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} object
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
write(entity, object, insideString = false) {
|
||||
let result = this.#objectWriter(object, insideString)
|
||||
write(entity, insideString = false) {
|
||||
let result = this.#objectWriter(entity, insideString)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ export default class GeneralSerializer extends ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} object
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
write(entity, object, insideString = false) {
|
||||
let result = this.wrap(this.subWrite(entity, [], object, insideString), object)
|
||||
write(entity, insideString = false) {
|
||||
let result = this.wrap(super.write(entity, insideString), entity)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,11 +270,14 @@ export default class Grammar {
|
||||
return P.seq(
|
||||
this.attributeName,
|
||||
valueSeparator,
|
||||
).chain(([attributeName, _1]) => this
|
||||
.grammarFor(entityType.attributes[attributeName], undefined)
|
||||
.map(attributeValue =>
|
||||
values => values[Utility.encodeKeyName(attributeName)] = attributeValue
|
||||
))
|
||||
).chain(([attributeName, _1]) => {
|
||||
attributeName = Utility.encodeKeyName(attributeName)
|
||||
return this
|
||||
.grammarFor(entityType.attributes[attributeName], undefined)
|
||||
.map(attributeValue =>
|
||||
values => values[attributeName] = attributeValue
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ export default class ISerializer {
|
||||
attributeSeparator = ",",
|
||||
trailingSeparator = false,
|
||||
attributeValueConjunctionSign = "=",
|
||||
attributeKeyPrinter = k => k.join(".")
|
||||
attributeKeyPrinter = k => k
|
||||
) {
|
||||
this.entityType = entityType
|
||||
this.attributePrefix = attributePrefix
|
||||
@@ -36,9 +36,9 @@ export default class ISerializer {
|
||||
return this.read(value)
|
||||
}
|
||||
|
||||
/** @param {T} object */
|
||||
serialize(object, insideString = false, entity = object) {
|
||||
return this.write(entity, object, insideString)
|
||||
/** @param {T} value */
|
||||
serialize(value, insideString = false) {
|
||||
return this.write(value, insideString)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,21 +52,46 @@ export default class ISerializer {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {T} object
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
write(entity, object, insideString) {
|
||||
throw new Error("Not implemented")
|
||||
write(entity, insideString) {
|
||||
let result = ""
|
||||
const attributes = /** @type {EntityConstructor} */(entity.constructor).attributes ?? {}
|
||||
const keys = Utility.mergeArrays(
|
||||
Object.keys(attributes),
|
||||
Object.keys(entity)
|
||||
)
|
||||
for (const key of keys) {
|
||||
const value = entity[key]
|
||||
if (value !== undefined && this.showProperty(entity, key)) {
|
||||
const isSerialized = Utility.isSerialized(entity, key)
|
||||
result += (result.length ? this.attributeSeparator : "")
|
||||
+ this.attributePrefix
|
||||
+ Utility.decodeKeyName(this.attributeKeyPrinter(key))
|
||||
+ this.attributeValueConjunctionSign
|
||||
+ (
|
||||
isSerialized
|
||||
? `"${this.writeValue(entity, key, true)}"`
|
||||
: this.writeValue(entity, key, insideString)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (this.trailingSeparator && result.length) {
|
||||
// append separator at the end if asked and there was printed content
|
||||
result += this.attributeSeparator
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {AnyValue} value
|
||||
* @param {String[]} fullKey
|
||||
* @param {String} key
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
writeValue(entity, value, fullKey, insideString) {
|
||||
writeValue(entity, key, insideString) {
|
||||
const value = entity[key]
|
||||
const type = Utility.getType(value)
|
||||
// @ts-expect-error
|
||||
const serializer = SerializerFactory.getSerializer(type)
|
||||
@@ -74,65 +99,20 @@ export default class ISerializer {
|
||||
throw new Error(`Unknown value type "${type.name}", a serializer must be registered in the SerializerFactory class, check initializeSerializerFactory.js`)
|
||||
}
|
||||
return serializer.write(
|
||||
value instanceof IEntity ? value : entity,
|
||||
value,
|
||||
entity[key],
|
||||
insideString
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {String[]} key
|
||||
* @param {Object} object
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
*/
|
||||
subWrite(entity, key, object, insideString) {
|
||||
let result = ""
|
||||
let fullKey = key.concat("")
|
||||
const last = fullKey.length - 1
|
||||
const attributes = /** @type {EntityConstructor} */(object.constructor).attributes
|
||||
const keys = attributes
|
||||
? Utility.mergeArrays(
|
||||
Object.keys(attributes),
|
||||
Object.keys(object)
|
||||
)
|
||||
: Object.keys(object)
|
||||
for (const property of keys) {
|
||||
fullKey[last] = property
|
||||
const value = object[property]
|
||||
if (value?.constructor === Object) {
|
||||
// Recursive call when finding an object
|
||||
result += (result.length ? this.attributeSeparator : "")
|
||||
+ this.subWrite(entity, fullKey, value, insideString)
|
||||
} else if (value !== undefined && this.showProperty(entity, object, fullKey, value)) {
|
||||
const isSerialized = Utility.isSerialized(entity, fullKey)
|
||||
result += (result.length ? this.attributeSeparator : "")
|
||||
+ this.attributePrefix
|
||||
+ Utility.decodeKeyName(this.attributeKeyPrinter(fullKey))
|
||||
+ this.attributeValueConjunctionSign
|
||||
+ (
|
||||
isSerialized
|
||||
? `"${this.writeValue(entity, value, fullKey, true)}"`
|
||||
: this.writeValue(entity, value, fullKey, insideString)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (this.trailingSeparator && result.length && fullKey.length === 1) {
|
||||
// append separator at the end if asked and there was printed content
|
||||
result += this.attributeSeparator
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
showProperty(entity, object, attributeKey, attributeValue) {
|
||||
showProperty(entity, key) {
|
||||
const attributes = /** @type {EntityConstructor} */(this.entityType).attributes
|
||||
const attribute = attributes[attributeKey]
|
||||
const attribute = attributes[key]
|
||||
const value = entity[key]
|
||||
if (attribute?.constructor === Object) {
|
||||
if (attribute.ignored) {
|
||||
return false
|
||||
}
|
||||
return !Utility.equals(attribute.value, attributeValue) || attribute.showDefault
|
||||
return !Utility.equals(attribute.value, value) || attribute.showDefault
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ export default class ObjectSerializer extends ISerializer {
|
||||
super(ObjectEntity, " ", "\n", false)
|
||||
}
|
||||
|
||||
showProperty(entity, object, attributeKey, attributeValue) {
|
||||
switch (attributeKey.toString()) {
|
||||
showProperty(entity, key) {
|
||||
switch (key) {
|
||||
case "Class":
|
||||
case "Name":
|
||||
case "CustomProperties":
|
||||
// Serielized separately, check write()
|
||||
return false
|
||||
}
|
||||
return super.showProperty(entity, object, attributeKey, attributeValue)
|
||||
return super.showProperty(entity, key)
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
@@ -43,21 +43,20 @@ export default class ObjectSerializer extends ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ObjectEntity} object
|
||||
* @param {ObjectEntity} entity
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
write(entity, object, insideString) {
|
||||
let result = `Begin Object Class=${object.Class.path} Name=${this.writeValue(entity, object.Name, "Name", insideString)}
|
||||
${this.subWrite(entity, [], object, insideString)
|
||||
+ object
|
||||
.CustomProperties.map(pin =>
|
||||
this.attributeSeparator
|
||||
+ this.attributePrefix
|
||||
+ "CustomProperties "
|
||||
+ SerializerFactory.getSerializer(PinEntity).serialize(pin)
|
||||
)
|
||||
.join("")}
|
||||
End Object\n`
|
||||
write(entity, insideString) {
|
||||
let result = `Begin Object Class=${entity.Class.path} Name=${this.writeValue(entity, "Name", insideString)}\n`
|
||||
+ super.write(entity, insideString)
|
||||
+ entity.CustomProperties.map(pin =>
|
||||
this.attributeSeparator
|
||||
+ this.attributePrefix
|
||||
+ "CustomProperties "
|
||||
+ SerializerFactory.getSerializer(PinEntity).serialize(pin)
|
||||
)
|
||||
.join("")
|
||||
+ "\nEnd Object\n"
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ export default class ToStringSerializer extends GeneralSerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} object
|
||||
* @param {T} entity
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
write(entity, object, insideString) {
|
||||
return !insideString && object.constructor === String
|
||||
? `"${Utility.escapeString(object.toString())}"` // String will have quotes if not inside a string already
|
||||
: Utility.escapeString(object.toString())
|
||||
write(entity, insideString) {
|
||||
return !insideString && entity.constructor === String
|
||||
? `"${Utility.escapeString(entity.toString())}"` // String will have quotes if not inside a string already
|
||||
: Utility.escapeString(entity.toString())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user