Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save siman/40365e98ac8ea2fb178794b06c56ef8d to your computer and use it in GitHub Desktop.
Save siman/40365e98ac8ea2fb178794b06c56ef8d to your computer and use it in GitHub Desktop.
// Copyright 2019 Jsgenesis.
//
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
use serde_derive::{Serialize, Deserialize};
use rstd::prelude::*;
use parity_codec::Codec;
use parity_codec_derive::{Decode, Encode};
use srml_support::{decl_event, decl_module, decl_storage, dispatch, ensure, fail, Parameter, StorageValue, StorageMap};
use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeDebug, MaybeSerializeDebug};
use system::{ensure_signed};
use system;
// mod mock;
mod tests;
/// Constants
/////////////////////////////////////////////////////////////////
const MAX_NUM_OF_PROPS_PER_CLASS: u16 = 30;
/// Error messages for dispatchables
const ERROR_NOT_IMPLEMENTED: &str = "Not implemented yet";
const MAX_NAME_LENGTH: u16 = 100;
const MAX_DESCRIPTION_LENGTH: u16 = 1000;
pub type ClassId = u64;
pub type EntityId = u64;
/// Convenient composite time stamp
// #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
// #[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
// pub struct BlockAndTime<BlockNumber, Moment> {
// block: BlockNumber,
// time: Moment
// }
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
pub struct Class {
id: ClassId,
/// For Person, think "height", "weight", etc.
/// Unlikely to be more than roughly 20ish, often less.
properties: Vec<PropertyTypeBox>,
/// All scehmas that are available for this class, think v0.0 Person, v.1.0 Person, etc.
schemas: Vec<ClassSchema>,
name: Vec<u8>,
description: Vec<u8>,
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
pub struct Entity {
id: EntityId,
/// The class id of this entity.
class_id: ClassId,
/// What schemas under which this entity of a class is available, think
/// v.2.0 Person schema for John , v3.0 Person schema for John
/// Unlikely to be more than roughly 20ish, assuming schemas for a given class eventually stableize, or that very old schema are eventually removed.
schemas: Vec<u16>, // indices of schema in corresponding class
/// Values for properties on class that are used by some schema used by this entity!
/// Length is no more than Class.properties.
values: Vec<(u16, PropertyValueBox)>, // Index is into properties vector of class. Fix anonymous type later.
name: Vec<u8>,
deleted: bool,
}
/// A schema defines what properties describe an entity
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
pub struct ClassSchema {
version: u16,
properties: Vec<u8> // indices into properties vector for the corresponding class
}
enum PropertyTypeBox {
Value(PropertyType),
Array(PropertyType)
}
enum PropertyValueBox {
Value(PropertyValue),
Array(PropertyArray)
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
pub struct Property {
prop_type: PropertyType,
required: bool,
name: Vec<u8>,
description: Vec<u8>,
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
pub enum PropertyType {
None,
Bool,
Uint16,
Uint32,
Uint64,
Int16,
Int32,
Int64,
Text(u32),
Internal(ClassId),
// External(ExternalProperty),
}
impl Default for PropertyType {
fn default() -> Self {
PropertyType::None
}
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
pub enum PropertyArray {
None,
BoolArray(Vec<bool>),
Uint16Array(Vec<u16>),
Uint32Array(Vec<u32>),
Uint64Array(Vec<u64>),
Int16Array(Vec<i16>),
Int32Array(Vec<i32>),
Int64Array(Vec<i64>),
TextArray(Vec<Vec<u8>>),
InternalArray(Vec<EntityId>),
// ExternalArray(Vec<ExternalPropertyType>),
}
pub enum PropertyValue {
None,
Bool(bool),
Uint16(u16),
Uint32(u32),
Uint64(u64),
Int16(i16),
Int32(i32),
Int64(i64),
Text(Vec<u8>),
Internal(EntityId),
// External(ExternalPropertyType),
}
impl Default for PropertyValue {
fn default() -> Self {
PropertyValue::None
}
}
pub trait Trait: system::Trait + timestamp::Trait + Sized {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
decl_storage! {
trait Store for Module<T: Trait> as VersionedStore {
pub ClassById get(class_by_id) config(): map ClassId => Class;
pub EntityById get(entity_by_id) config(): map EntityId => Entity;
pub NextClassId get(next_class_id) config(): ClassId;
pub NextEntityId get(next_entity_id) config(): EntityId;
}
}
decl_event!(
pub enum Event<T>
where
<T as system::Trait>::AccountId,
{
ClassCreated(AccountId, ClassId),
ClassPropertyAdded(AccountId, ClassId),
ClassSchemaAdded(AccountId, ClassId),
EntityCreated(AccountId, EntityId),
EntityUpdated(AccountId, EntityId),
EntityDeleted(AccountId, EntityId),
}
);
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event<T>() = default;
}
}
impl<T: Trait> Module<T> {
pub fn create_class(name: Vec<u8>, description: Vec<u8>, properties: Vec<Property>, schemas: Vec<ClassSchema>) -> Result<ClassId, &'static str> {
// TODO impl
// let class_id = <NextClassId<T>>::get();
// // Create new category
// let new_class = Class {
// // TODO finish
// };
// // Insert category in map
// <ClassById<T>>::insert(new_class.id, new_class);
// // Update other things
// <NextClassId<T>>::put(class_id + 1);
// // Generate event
// Self::deposit_event(RawEvent::ClassCreated(account.clone(), class_id));
Err(ERROR_NOT_IMPLEMENTED)
}
pub fn add_class_property(class_id: ClassId, property: Property) -> Result<u16, &'static str> {
// TODO impl
Err(ERROR_NOT_IMPLEMENTED)
}
pub fn add_class_schema(class_id: ClassId, schema: ClassSchema) -> dispatch::Result {
// TODO impl
Err(ERROR_NOT_IMPLEMENTED)
}
pub fn create_entity(name: Vec<u8>, class_id: ClassId, schema_indices: Vec<u16>, property_values: Vec<(u16, PropertyValue)>) -> Result<EntityId, &'static str>{
// TODO impl
Err(ERROR_NOT_IMPLEMENTED)
}
pub fn update_entity(entity_id: EntityId, schema_indices: Vec<u16>, property_values: Vec<(u16, PropertyValue)>) -> dispatch::Result {
// TODO impl
Err(ERROR_NOT_IMPLEMENTED)
}
pub fn delete_entity(entity_id: EntityId) -> dispatch::Result {
// TODO impl
Err(ERROR_NOT_IMPLEMENTED)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment