├── .gitignore ├── Cargo.toml ├── apache_license.txt ├── changelog.txt ├── docchi_archiver2 ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── error.rs │ ├── imp │ ├── mod.rs │ ├── read_archive.rs │ ├── read_archive_data_from_directory.rs │ ├── resume_archive.rs │ ├── structs │ │ ├── archive_data.rs │ │ ├── archive_options.rs │ │ ├── archiver.rs │ │ ├── hash_thread.rs │ │ └── mod.rs │ ├── write_archive.rs │ └── write_items.rs │ ├── json │ ├── general │ │ ├── moikko.json5 │ │ ├── nazofile.txt │ │ ├── root.json5 │ │ └── subfo │ │ │ ├── iruka.json5 │ │ │ └── nazofile2.txt │ └── simple │ │ ├── hoge.json5 │ │ ├── iruka.json5 │ │ ├── root.json5 │ │ └── siyou.json5 │ ├── lib.rs │ ├── output │ ├── general │ │ ├── moikko.json5 │ │ ├── nazofile.txt │ │ ├── root.json5 │ │ └── subfo │ │ │ ├── iruka.json5 │ │ │ └── nazofile2.txt │ └── general_to_simple │ │ ├── moikko.json5 │ │ └── root.json5 │ └── testing │ ├── archive_test.rs │ ├── archive_test_old.rs │ ├── bench_convert.rs │ ├── error_test.rs │ ├── general_to_simple_test.rs │ ├── mod.rs │ └── resume_test.rs ├── docchi_compaction ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── basic_compaction.rs │ ├── enc_dec │ ├── decimal_lib.rs │ ├── decode.rs │ ├── decode_from_slice.rs │ ├── encode.rs │ ├── encode_to_vec.rs │ ├── kihon_from_tag.rs │ ├── mod.rs │ ├── reader.rs │ ├── signed_bytes.rs │ ├── tag_reader.rs │ ├── tag_storage.rs │ ├── var_int.rs │ └── writer.rs │ ├── error.rs │ ├── kval_enum.rs │ ├── lib.rs │ ├── string_compaction.rs │ ├── testing │ ├── mod.rs │ ├── test_enc_dec.rs │ └── test_string_compaction.rs │ ├── url_string │ ├── b8s_and_b6s.rs │ ├── char_and_b6.rs │ └── mod.rs │ ├── 仕様.txt │ └── 仕様_old.txt ├── docchi_core ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── error.rs │ ├── imp │ ├── intf │ │ ├── citem.rs │ │ ├── clist.rs │ │ ├── clist_const.rs │ │ ├── clist_iter_const.rs │ │ ├── ctable_const.rs │ │ ├── member_desc.rs │ │ ├── mitem.rs │ │ ├── mlist_const.rs │ │ ├── mlist_iter_const.rs │ │ ├── mlist_iter_mut.rs │ │ ├── mlist_mut.rs │ │ ├── mlist_ptr.rs │ │ ├── mod.rs │ │ ├── ref_desc.rs │ │ ├── root.rs │ │ └── table.rs │ ├── json_to_rust │ │ ├── array_null.rs │ │ ├── construct_root.rs │ │ ├── get_id.rs │ │ ├── get_old.rs │ │ ├── get_refs.rs │ │ ├── json_array_to_rust.rs │ │ ├── json_item_to_rust.rs │ │ ├── json_name.rs │ │ ├── json_obj_to_rust.rs │ │ ├── list │ │ │ ├── get_default.rs │ │ │ ├── get_list_items.rs │ │ │ ├── json_list_to_rust.rs │ │ │ ├── list_attribute.rs │ │ │ └── mod.rs │ │ ├── mod.rs │ │ ├── names.rs │ │ ├── roots │ │ │ ├── archive_data_to_root.rs │ │ │ ├── archive_file_to_root.rs │ │ │ ├── archive_src_dir.rs │ │ │ ├── json_dir_to_root.rs │ │ │ ├── json_file_to_rust.rs │ │ │ └── mod.rs │ │ ├── set_empty_mils │ │ │ ├── initialize_empty_mils.rs │ │ │ ├── mod.rs │ │ │ ├── set_empty_mils.rs │ │ │ └── set_empty_mils_root.rs │ │ ├── tmp │ │ │ ├── mod.rs │ │ │ ├── tmp_list.rs │ │ │ └── tmp_obj.rs │ │ └── validation │ │ │ ├── mod.rs │ │ │ ├── validate_data.rs │ │ │ ├── validate_list.rs │ │ │ ├── validate_list_def.rs │ │ │ ├── validate_list_item.rs │ │ │ ├── validate_mut_list.rs │ │ │ ├── validate_old_def_mem.rs │ │ │ ├── validate_ref_def.rs │ │ │ ├── validate_refs.rs │ │ │ └── validate_root.rs │ ├── mod.rs │ ├── rust_to_json │ │ ├── get_param.rs │ │ ├── list │ │ │ ├── default_to_json.rs │ │ │ ├── inner_mut_def_to_json.rs │ │ │ ├── list_type_to_string.rs │ │ │ ├── mod.rs │ │ │ ├── ref_def_obj_to_json.rs │ │ │ ├── tmp_json_list.rs │ │ │ ├── tmp_list_to_json.rs │ │ │ ├── tmp_obj_to_json.rs │ │ │ ├── tmp_refs_to_json.rs │ │ │ └── value_map_to_json.rs │ │ ├── mod.rs │ │ ├── name_with_suffix.rs │ │ ├── root_to_json.rs │ │ ├── rust_array_to_json.rs │ │ ├── rust_value_to_json_value.rs │ │ └── string_set_to_json.rs │ ├── structs │ │ ├── array_type.rs │ │ ├── docchi_archive.rs │ │ ├── json_file.rs │ │ ├── linked_m.rs │ │ ├── linked_map_iter.rs │ │ ├── linked_map_iter_mut.rs │ │ ├── linked_map_unsafe_iter.rs │ │ ├── list_def_obj.rs │ │ ├── list_sab_value.rs │ │ ├── list_type.rs │ │ ├── list_value.rs │ │ ├── meta_table.rs │ │ ├── mod.rs │ │ ├── mut_list_def.rs │ │ ├── my_json.rs │ │ ├── null_or.rs │ │ ├── param_type.rs │ │ ├── qv.rs │ │ ├── ref_def_obj.rs │ │ ├── ref_value.rs │ │ ├── root_def_obj.rs │ │ ├── root_obj.rs │ │ ├── root_sab_value.rs │ │ ├── root_value.rs │ │ ├── rust_array.rs │ │ ├── rust_list.rs │ │ ├── rust_param.rs │ │ ├── rust_string.rs │ │ ├── rust_value.rs │ │ ├── util │ │ │ ├── hash_m.rs │ │ │ ├── identity_equal_trait.rs │ │ │ ├── mod.rs │ │ │ └── set_sabun.rs │ │ └── var_type.rs │ └── version_adjuster │ │ ├── adjust_mut_list.rs │ │ ├── adjust_mut_list_item_ref.rs │ │ ├── adjust_mut_list_item_sabun.rs │ │ ├── mod.rs │ │ └── version_adjuster.rs │ ├── json_dir │ ├── json_dir_siyou.txt │ ├── json_siyou │ │ ├── root.json5 │ │ ├── someData.json5 │ │ └── someStr.json5 │ └── version_adjuster │ │ ├── new │ │ └── root.json5 │ │ └── old │ │ └── root.json5 │ ├── lib.rs │ ├── old │ ├── json_siyou_old.rs │ ├── list_idの互換性に対する考え.txt │ ├── mod.rs │ ├── objectからobjectを生やすか.txt │ ├── renameに関して.txt │ ├── なぜデフォルト値が必要なのか.txt │ └── ロードマップ.txt │ ├── structs │ └── mod.rs │ └── testing │ ├── check_type_size.rs │ ├── initialize_performance_test.rs │ ├── json_to_rust_and_json.rs │ ├── mod.rs │ ├── test_linked_m.rs │ └── test_version_adjuster.rs ├── docchi_diff ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── diff_error.rs │ ├── imp │ ├── apply │ │ ├── apply_list_diff.rs │ │ ├── apply_lists.rs │ │ ├── apply_params.rs │ │ ├── apply_refs.rs │ │ ├── apply_root_diff.rs │ │ ├── diff_to_new_list.rs │ │ ├── mod.rs │ │ ├── modify_item_from_diff.rs │ │ └── new_item_from_diff.rs │ ├── apply_diff.rs │ ├── get_diff.rs │ ├── mod.rs │ ├── prepare │ │ ├── compare_items.rs │ │ ├── get_mlist_diff.rs │ │ ├── get_root_diff.rs │ │ ├── mod.rs │ │ ├── new_item.rs │ │ └── new_list.rs │ ├── read │ │ ├── get_null.rs │ │ ├── get_undefined.rs │ │ ├── mod.rs │ │ ├── read_list.rs │ │ ├── read_lists.rs │ │ ├── read_lists_numbers.rs │ │ ├── read_param.rs │ │ ├── read_params.rs │ │ ├── read_refs.rs │ │ ├── read_root.rs │ │ ├── read_store_ids.rs │ │ └── reader.rs │ ├── structs_read.rs │ ├── structs_write.rs │ └── write │ │ ├── mod.rs │ │ ├── store_ids.rs │ │ ├── write_list.rs │ │ ├── write_param.rs │ │ ├── write_refs.rs │ │ ├── write_root.rs │ │ └── write_store_ids.rs │ └── lib.rs ├── docchi_fs ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── error.rs │ ├── imp │ ├── common │ │ ├── apply_items.rs │ │ ├── archive │ │ │ ├── get_archive_path.rs │ │ │ └── mod.rs │ │ ├── current_src │ │ │ ├── current_src.rs │ │ │ ├── current_src_info.rs │ │ │ ├── current_src_map.rs │ │ │ └── mod.rs │ │ ├── list │ │ │ ├── file_data.rs │ │ │ ├── find_next_dir.rs │ │ │ ├── list_files.rs │ │ │ ├── list_files_iterator.rs │ │ │ └── mod.rs │ │ ├── mod.rs │ │ └── path │ │ │ ├── created_time_file.rs │ │ │ ├── get_hash_times.rs │ │ │ ├── hash.rs │ │ │ ├── hash_dir_path.rs │ │ │ ├── mod.rs │ │ │ ├── prepare_hash_dir.rs │ │ │ ├── remove_hash_dir.rs │ │ │ └── reserved_filename.rs │ ├── filesys │ │ ├── docchi_mutex.rs │ │ ├── list_docchi_files.rs │ │ ├── load_docchi_file.rs │ │ ├── mod.rs │ │ ├── remove_docchi_file.rs │ │ ├── save_cache_item.rs │ │ ├── save_cache_map.rs │ │ ├── save_dir_info.rs │ │ └── save_docchi_file.rs │ ├── history │ │ ├── algo │ │ │ ├── calc_next_phase.rs │ │ │ ├── history_options.rs │ │ │ ├── mod.rs │ │ │ ├── phase_data.rs │ │ │ ├── phase_data_item.rs │ │ │ └── should_shift_to_parent_phase.rs │ │ ├── current_root_obj_info │ │ │ ├── current_root_obj_info.rs │ │ │ ├── fifo_thread.rs │ │ │ ├── history_cache_item.rs │ │ │ ├── history_cache_map.rs │ │ │ ├── mod.rs │ │ │ └── mutex_g.rs │ │ ├── diff_and_cache │ │ │ ├── accumulate_diff.rs │ │ │ ├── cache.rs │ │ │ ├── diff_src.rs │ │ │ ├── diff_value.rs │ │ │ ├── docchi_cache.rs │ │ │ ├── docchi_diff.rs │ │ │ ├── docchi_src.rs │ │ │ ├── impl_cache_for_docchi_cache.rs │ │ │ ├── mod.rs │ │ │ └── open_diff_file_without_metadata.rs │ │ ├── file_hist │ │ │ ├── ancestors.rs │ │ │ ├── create_file_history.rs │ │ │ ├── file_histories.rs │ │ │ ├── file_history.rs │ │ │ ├── file_history_item.rs │ │ │ ├── history_file_data.rs │ │ │ └── mod.rs │ │ ├── file_name │ │ │ ├── analyze_file_name.rs │ │ │ ├── calc_filename.rs │ │ │ ├── file_name_props.rs │ │ │ └── mod.rs │ │ ├── fs │ │ │ ├── derive.rs │ │ │ ├── derive_impl.rs │ │ │ ├── first.rs │ │ │ ├── load.rs │ │ │ ├── mod.rs │ │ │ ├── next.rs │ │ │ ├── start_new.rs │ │ │ ├── write_phase_0.rs │ │ │ └── write_phase_file.rs │ │ ├── history_info.rs │ │ ├── mod.rs │ │ ├── pub_fn │ │ │ ├── list_histories.rs │ │ │ ├── load_history_file.rs │ │ │ ├── mod.rs │ │ │ └── save_history_file.rs │ │ ├── readme.md │ │ └── remove │ │ │ ├── btree_zipper.rs │ │ │ ├── composite_remover.rs │ │ │ ├── history_remover.rs │ │ │ ├── history_remover_item.rs │ │ │ └── mod.rs │ └── mod.rs │ ├── json_dir │ ├── simple │ │ └── root.json5 │ ├── simple_mod1 │ │ └── root.json5 │ ├── simple_mod2 │ │ └── root.json5 │ ├── simple_mod3 │ │ └── root.json5 │ └── simple_mod4 │ │ └── root.json5 │ ├── lib.rs │ ├── test_diff_history │ ├── mod.rs │ ├── show_dir_contents_diff_history.rs │ └── test_diff_his.rs │ ├── test_fs │ ├── copy_dir_all.rs │ ├── mod.rs │ ├── save_test.rs │ ├── show_dir_contents_fs.rs │ ├── test_fifo_thread.rs │ └── test_hex_file_name.rs │ └── test_simple_history │ ├── history2 │ ├── create_file_history2.rs │ ├── file_history2.rs │ ├── file_history_item2.rs │ └── mod.rs │ ├── mod.rs │ ├── show_dir_contents_history.rs │ ├── simple_diff │ ├── create_sd_diff.rs │ ├── mod.rs │ ├── sd_cache.rs │ ├── sd_data.rs │ ├── sd_data_diff_src.rs │ ├── sd_diff.rs │ └── sd_diff_diff_value.rs │ ├── test_cumulative_limit_count.rs │ ├── test_cumulative_limit_nth.rs │ ├── test_load_and_save.rs │ ├── test_max_phase0.rs │ ├── test_max_phase0_with_cumu.rs │ └── test_simple_diff_files.rs ├── docchi_intf ├── Cargo.toml ├── apache_license.txt ├── license.txt ├── readme.md └── src │ ├── error.rs │ ├── imp │ ├── generate_accessor_from_json_dir.rs │ ├── generate_interface.rs │ ├── generate_root_source.rs │ ├── mod.rs │ ├── structs │ │ ├── cil_source.rs │ │ ├── citem_source.rs │ │ ├── clist_source.rs │ │ ├── mil_source.rs │ │ ├── mitem_source.rs │ │ ├── mlist_source.rs │ │ ├── mod.rs │ │ ├── param_source.rs │ │ ├── ref_source.rs │ │ ├── refs_source.rs │ │ ├── root_source.rs │ │ ├── source_builder.rs │ │ └── table_source.rs │ ├── to_member_source.rs │ └── util │ │ ├── into_qv.rs │ │ ├── mod.rs │ │ ├── to_type_name.rs │ │ ├── with_old.rs │ │ └── with_var.rs │ └── lib.rs ├── docchi_json5 ├── Cargo.toml ├── apache_license.txt ├── json5_rs_licence.txt ├── licence.txt ├── readme.md └── src │ ├── de.rs │ ├── deserialize_item.rs │ ├── error.rs │ ├── json5.pest │ ├── jval.rs │ ├── lib.rs │ └── test.rs ├── docchi_manual ├── Cargo.toml ├── manual │ ├── a1_hello_world_hello_world.md.md │ ├── a3_docchi_langs_basics_docchi_params_generate.rs.md │ ├── a3_docchi_langs_basics_docchi_params_root.json5.md │ ├── a3_docchi_langs_basics_params_test.rs.md │ ├── a4_clist_cil_root.json5.md │ ├── a4_clist_clist_root.json5.md │ ├── a4_clist_use_cil.rs.md │ ├── a5_mlist_mil_root.json5.md │ ├── a5_mlist_mlist_root.json5.md │ ├── a5_mlist_use_mil.rs.md │ ├── a6_table_table_root.json5.md │ ├── a6_table_use_table.rs.md │ ├── a7_split_docchi_src_split_src.md.md │ ├── b1_save_docchi_files_load_docchi_file.rs.md │ ├── b1_save_docchi_files_save_docchi_file_test.rs.md │ ├── b1_save_docchi_files_save_docchi_files.md.md │ ├── b2_save_history_files_algorithm_of_history.md.md │ ├── b2_save_history_files_directory_composition_and_how_to_handle.md.md │ ├── b2_save_history_files_load_history_file_test.rs.md │ ├── b2_save_history_files_save_history_file_test.rs.md │ ├── b2_save_history_files_whats_docchi_history.md.md │ ├── b3_1_clist_and_mlist_clist_and_mlist.md.md │ ├── b3_1_clist_and_mlist_separate_undefined_list.md.md │ ├── b3_conversion_conversion.md.md │ └── index.md └── src │ ├── a1_hello_world │ ├── hello_world.md │ ├── hello_world_accessor.rs │ ├── hello_world_generate.rs │ ├── hello_world_save_test.rs │ ├── mod.rs │ └── src_dir │ │ └── root.json5 │ ├── a3_docchi_langs_basics │ ├── docchi_params │ │ └── root.json5 │ ├── docchi_params_accessor.rs │ ├── docchi_params_generate.rs │ ├── mod.rs │ └── params_test.rs │ ├── a4_clist │ ├── cil │ │ └── root.json5 │ ├── cil_accessor.rs │ ├── cil_generate.rs │ ├── clist │ │ └── root.json5 │ ├── clist_accessor.rs │ ├── clist_generate.rs │ ├── mod.rs │ └── use_cil.rs │ ├── a5_mlist │ ├── mil │ │ └── root.json5 │ ├── mil_accessor.rs │ ├── mil_generate.rs │ ├── mlist │ │ └── root.json5 │ ├── mlist_accessor.rs │ ├── mlist_generate.rs │ ├── mod.rs │ └── use_mil.rs │ ├── a6_table │ ├── mod.rs │ ├── table │ │ └── root.json5 │ ├── table_accessor.rs │ ├── table_generate.rs │ └── use_table.rs │ ├── a7_split_docchi_src │ ├── jsons │ │ ├── json │ │ │ └── root.json5 │ │ └── splitted │ │ │ ├── int.json5 │ │ │ ├── list.json5 │ │ │ ├── root.json5 │ │ │ └── string.json5 │ ├── mod.rs │ ├── split_src.md │ └── split_src_test.rs │ ├── b1_save_docchi_files │ ├── load_docchi_file.rs │ ├── mod.rs │ ├── save_docchi_file_test.rs │ ├── save_docchi_files.md │ ├── save_docchi_files_accessor.rs │ ├── save_docchi_files_generate.rs │ └── src_dir │ │ └── root.json5 │ ├── b2_save_history_files │ ├── algorithm_of_history.md │ ├── directory_composition_and_how_to_handle.md │ ├── load_history_file_test.rs │ ├── mod.rs │ ├── save_history_file_test.rs │ ├── save_history_files_accessor.rs │ ├── save_history_files_generate.rs │ ├── src_dir │ │ └── root.json5 │ └── whats_docchi_history.md │ ├── b3_1_clist_and_mlist │ ├── clist_and_mlist.md │ ├── clist_new_accessor.rs │ ├── clist_new_adjust_test.rs │ ├── clist_new_generate.rs │ ├── clist_old_accessor.rs │ ├── clist_old_generate.rs │ ├── clist_old_test.rs │ ├── jsons │ │ ├── clist_new │ │ │ └── root.json5 │ │ ├── clist_old │ │ │ └── root.json5 │ │ ├── mlist_new │ │ │ └── root.json5 │ │ ├── mlist_old │ │ │ └── root.json5 │ │ ├── no_data │ │ │ └── root.json5 │ │ ├── undefiable_list │ │ │ └── root.json5 │ │ └── undefiable_list_separated │ │ │ ├── list!.json5 │ │ │ └── root.json5 │ ├── mlist_new_accessor.rs │ ├── mlist_new_adjust_test.rs │ ├── mlist_new_generate.rs │ ├── mlist_old_accessor.rs │ ├── mlist_old_generate.rs │ ├── mlist_old_test.rs │ ├── mod.rs │ ├── separate_undefined_list.md │ ├── undefiable_list_accessor.rs │ ├── undefiable_list_generate.rs │ └── undefiable_list_test.rs │ ├── b3_conversion │ ├── conversion.md │ ├── conversion_generate.rs │ ├── conversion_test.rs │ ├── jsons │ │ ├── new │ │ │ └── root.json5 │ │ ├── new2 │ │ │ └── root.json5 │ │ └── old │ │ │ └── root.json5 │ ├── mod.rs │ ├── new2_accessor.rs │ ├── new2_accessor_wrapper.rs │ ├── new_accessor.rs │ ├── new_accessor_wrapper.rs │ └── old_accessor.rs │ ├── lib.rs │ ├── make_manual │ ├── get_content.rs │ ├── make_index_page.rs │ ├── make_manual.rs │ ├── make_page.rs │ ├── manual │ │ └── root.json5 │ ├── manual_accessor.rs │ ├── manual_builder.rs │ ├── manual_generate.rs │ ├── mod.rs │ ├── sample │ │ ├── a.md │ │ ├── b.md │ │ └── index.md │ └── write_page.rs │ └── sample_test │ ├── mod.rs │ ├── sample_code │ ├── clist_new_accessor.rs │ ├── clist_new_adjust_test.rs │ ├── clist_new_generate.rs │ ├── clist_old_accessor.rs │ ├── clist_old_generate.rs │ ├── clist_old_test.rs │ ├── efficiency.md │ ├── history.md │ ├── mlist_new_accessor.rs │ ├── mlist_new_adjust_test.rs │ ├── mlist_new_generate.rs │ ├── mlist_old_accessor.rs │ ├── mlist_old_generate.rs │ ├── mlist_old_test.rs │ ├── mod.rs │ ├── ref1_accessor.rs │ ├── ref1_generate.rs │ ├── ref1_test.rs │ ├── ref2_accessor.rs │ ├── ref2_generate.rs │ ├── ref2_test.rs │ ├── ref2_wrapper.rs │ ├── ref_and_enum.md │ ├── rpg2_accessor.rs │ ├── rpg2_accessor_wrapper.rs │ ├── rpg2_generate.rs │ ├── rpg2_test_nottest.rs │ ├── version_awareness.md │ ├── version_awareness_accessor.rs │ ├── version_awareness_accessor2.rs │ ├── version_awareness_accessor_wrapper.rs │ ├── version_awareness_accessor_wrapper2.rs │ ├── version_awareness_generate.rs │ └── version_awareness_test.rs │ └── sample_code_json │ ├── clist_new │ └── root.json5 │ ├── clist_old │ └── root.json5 │ ├── mlist_new │ └── root.json5 │ ├── mlist_old │ └── root.json5 │ ├── ref1 │ └── root.json5 │ ├── ref2 │ └── root.json5 │ ├── rpg1 │ └── root.json5 │ ├── rpg2 │ ├── herb.json5 │ ├── root.json5 │ └── sword.json5 │ └── version_aware │ ├── a.txt │ ├── new │ └── root.json5 │ ├── new2 │ └── root.json5 │ └── old │ └── root.json5 ├── docchi_temporal_test ├── Cargo.toml └── src │ ├── benchan │ ├── benchanmark.rs │ ├── mod.rs │ └── threadpool_bench.rs │ ├── lib.rs │ ├── siyou │ ├── generate_siyou.rs │ ├── mod.rs │ └── siyou_generated.rs │ └── temporal_test.rs ├── docchi_test ├── Cargo.toml └── src │ ├── bench │ ├── from_le_bytes.rs │ └── mod.rs │ ├── diff │ ├── diff_big_structure │ │ └── root.json5 │ ├── diff_list │ │ └── root.json5 │ ├── diff_param │ │ └── root.json5 │ ├── diff_ref │ │ └── root.json5 │ ├── generate_for_test_big_structure.rs │ ├── generate_for_test_list.rs │ ├── generate_for_test_params.rs │ ├── generate_for_test_ref.rs │ ├── generated_test_big_structure.rs │ ├── generated_test_list.rs │ ├── generated_test_params.rs │ ├── generated_test_ref.rs │ ├── mod.rs │ ├── test_big_structure.rs │ ├── test_list.rs │ ├── test_params.rs │ ├── test_ref.rs │ └── util │ │ ├── generate_intf_src.rs │ │ └── mod.rs │ ├── fs_test │ ├── history_accum_test │ │ ├── accum_save_test.rs │ │ ├── hello_history_accessor.rs │ │ ├── hello_history_generate.rs │ │ ├── mod.rs │ │ ├── src_dir │ │ │ └── root.json5 │ │ └── src_dir_copy │ │ │ └── root.json5 │ ├── mod.rs │ ├── test_save_async │ │ ├── mod.rs │ │ ├── src_dir │ │ │ └── root.json5 │ │ ├── test_save_async.rs │ │ ├── test_save_async_accessor.rs │ │ ├── test_save_async_generate.rs │ │ ├── test_thread.rs │ │ └── test_thread_file.dat │ ├── test_save_history_nb │ │ ├── mod.rs │ │ ├── src_dir │ │ │ └── root.json5 │ │ ├── test_save_history_async.rs │ │ ├── test_save_history_async_accessor.rs │ │ └── test_save_history_async_generate.rs │ └── test_save_history_vacant │ │ ├── mod.rs │ │ ├── src_dir │ │ └── root.json5 │ │ ├── test_save_history_vacant.rs │ │ ├── test_save_history_vacant_accessor.rs │ │ └── test_save_history_vacant_generate.rs │ └── lib.rs ├── mit_license.txt ├── publish.bat ├── readme.md ├── roadmap.md ├── src ├── core.rs ├── fs.rs ├── intf.rs └── lib.rs └── 並列化仕様.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | /.idea/ 4 | save_dir/ 5 | history_dir/ 6 | dat_dir/ 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "A diff-based data management language to implement unlimited undo, auto-save for games, and cloud-apps which needs to retain every change." 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["json5","diff","binary","undo","autosave"] 12 | categories = ["filesystem","compression","data-structures"] 13 | documentation = "https://github.com/dochy-ksti/docchi/blob/master/docchi_manual/manual/index.md" 14 | 15 | 16 | [workspace] 17 | members = [ 18 | "docchi_json5", 19 | "docchi_compaction", 20 | "docchi_archiver2", 21 | "docchi_core", 22 | "docchi_diff", 23 | "docchi_fs", 24 | "docchi_intf", 25 | "docchi_manual", 26 | "docchi_temporal_test", 27 | "docchi_test", 28 | ] 29 | 30 | [dependencies] 31 | 32 | docchi_core = { path="docchi_core", version="0.8" } 33 | docchi_fs = { path="docchi_fs", version="0.8"} 34 | docchi_intf = { path="docchi_intf", version="0.8"} 35 | 36 | -------------------------------------------------------------------------------- /apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | 0.8.0 2 | 3 | -created ComError, the error type for docchi_compaction 4 | -implemented std::error::Error for all our error types: 5 | NouArcError, ComError, CoreError, DiffError, FsError, IntfError, docchi_json5::MyError 6 | -removed docchi::error::DpError. We recommend using anyhow::Error as a replacement. -------------------------------------------------------------------------------- /docchi_archiver2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_archiver2" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "A serializer which compresses integers" 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["archiver", "Snappy", "MetroHash"] 12 | 13 | [dependencies] 14 | docchi_compaction = { path="../docchi_compaction", version="0.8" } 15 | metrohash = "1.0.6" 16 | snap = "1.0.1" 17 | anyhow = "1.0.34" 18 | with_capacity_safe = "0.4" 19 | rayon = "1.5.1" -------------------------------------------------------------------------------- /docchi_archiver2/apache_license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dochy-ksti/docchi/ba87777af3ecacb24b097fee8ffaa852bbcc20ff/docchi_archiver2/apache_license.txt -------------------------------------------------------------------------------- /docchi_archiver2/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_archiver2/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) 2 | 3 | -------------------------------------------------------------------------------- /docchi_archiver2/src/imp/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod read_archive_data_from_directory; 2 | pub(crate) mod structs; 3 | pub(crate) mod write_archive; 4 | pub(crate) mod write_items; 5 | pub(crate) mod read_archive; 6 | -------------------------------------------------------------------------------- /docchi_archiver2/src/imp/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod archive_options; 2 | pub(crate) mod archive_data; 3 | pub(crate) mod archiver; 4 | pub(crate) mod hash_thread; 5 | -------------------------------------------------------------------------------- /docchi_archiver2/src/imp/write_items.rs: -------------------------------------------------------------------------------- 1 | use crate::ArcResult; 2 | use std::io::Write; 3 | use docchi_compaction::kval_enum::KVal; 4 | use docchi_compaction::basic_compaction::{comp_str, comp_int}; 5 | use std::collections::BTreeMap; 6 | 7 | pub(crate) fn write_items(items : BTreeMap>, writer : &mut W) -> ArcResult<()>{ 8 | let mut kvals : Vec = Vec::with_capacity(items.len()); 9 | let mut comps : Vec> = Vec::with_capacity(items.len()); 10 | 11 | kvals.push(comp_int(items.len() as i64)); 12 | for (path, compressed) in items{ 13 | kvals.push(comp_str(path)); 14 | kvals.push(comp_int(compressed.len() as i64)); 15 | comps.push(compressed); 16 | } 17 | 18 | docchi_compaction::encode(&kvals, writer)?; 19 | 20 | for comp in &comps{ 21 | writer.write_all(comp)?; 22 | } 23 | 24 | Ok(()) 25 | } -------------------------------------------------------------------------------- /docchi_archiver2/src/json/general/moikko.json5: -------------------------------------------------------------------------------- 1 | [0,0,0] -------------------------------------------------------------------------------- /docchi_archiver2/src/json/general/nazofile.txt: -------------------------------------------------------------------------------- 1 | 謎のファイルだよー -------------------------------------------------------------------------------- /docchi_archiver2/src/json/general/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | int : 0, 3 | float : 0.0 4 | } -------------------------------------------------------------------------------- /docchi_archiver2/src/json/general/subfo/iruka.json5: -------------------------------------------------------------------------------- 1 | [2,3,4] -------------------------------------------------------------------------------- /docchi_archiver2/src/json/general/subfo/nazofile2.txt: -------------------------------------------------------------------------------- 1 | 謎のファイル2だああああ -------------------------------------------------------------------------------- /docchi_archiver2/src/json/simple/hoge.json5: -------------------------------------------------------------------------------- 1 | "strvalue" -------------------------------------------------------------------------------- /docchi_archiver2/src/json/simple/iruka.json5: -------------------------------------------------------------------------------- 1 | [2,3,4] -------------------------------------------------------------------------------- /docchi_archiver2/src/json/simple/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | int : 0, 3 | float : 0.0 4 | } -------------------------------------------------------------------------------- /docchi_archiver2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny(unreachable_pub)] 2 | #![deny(unused_crate_dependencies)] 3 | 4 | mod imp; 5 | #[cfg(test)] 6 | #[allow(dead_code, unused_imports)] 7 | mod testing; 8 | mod error; 9 | 10 | 11 | 12 | pub type ArcResult = std::result::Result; 13 | pub use error::NouArcError; 14 | 15 | pub use imp::read_archive_data_from_directory::read_archive_data_from_directory; 16 | pub use imp::read_archive::read_archive; 17 | pub use imp::write_archive::write_archive; 18 | 19 | pub use imp::structs::archive_data::{ArchiveData, ArchiveDataItem}; 20 | 21 | pub use imp::structs::archive_options::ArchiveOptions; 22 | pub use imp::structs::archive_options::ArchiveOptionsBuilder; 23 | 24 | -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general/moikko.json5: -------------------------------------------------------------------------------- 1 | [0,0,0] -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general/nazofile.txt: -------------------------------------------------------------------------------- 1 | 謎のファイルだよー -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | int : 0, 3 | float : 0.0 4 | } -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general/subfo/iruka.json5: -------------------------------------------------------------------------------- 1 | [2,3,4] -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general/subfo/nazofile2.txt: -------------------------------------------------------------------------------- 1 | 謎のファイル2だああああ -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general_to_simple/moikko.json5: -------------------------------------------------------------------------------- 1 | [0,0,0] -------------------------------------------------------------------------------- /docchi_archiver2/src/output/general_to_simple/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | int : 0, 3 | float : 0.0 4 | } -------------------------------------------------------------------------------- /docchi_archiver2/src/testing/general_to_simple_test.rs: -------------------------------------------------------------------------------- 1 | // use crate::{ArcResult, ArchiveOptions, resume_archive, read_archive_data, ArchiveOptionsBuilder}; 2 | // use crate::imp::create_archive_from_directory::CreateArchiveFromDirectory; 3 | // use anyhow::anyhow; 4 | // 5 | // //#[test] 6 | // fn general_to_simple_test() -> ArcResult<()>{ 7 | // let mut buf : Vec = Vec::new(); 8 | // if let CreateArchiveFromDirectory::WrittenSuccessfully(_a,_b) = 9 | // crate::imp::create_archive_from_directory::create_archive_from_directory( 10 | // "./src/json/general", &mut buf, |_| false, &ArchiveOptions::from(ArchiveOptionsBuilder{ 11 | // archive_subfolders : false, 12 | // extensions_archived : vec!["json5"], 13 | // })?)?{ 14 | // 15 | // let archive = read_archive_data(&mut buf.as_slice())?; 16 | // 17 | // resume_archive("./src/output/general_to_simple", &archive, true)?; 18 | // Ok(()) 19 | // } else{ 20 | // unreachable!() 21 | // } 22 | // } 23 | // 24 | -------------------------------------------------------------------------------- /docchi_archiver2/src/testing/mod.rs: -------------------------------------------------------------------------------- 1 | mod bench_convert; 2 | mod error_test; 3 | mod archive_test; 4 | mod general_to_simple_test; 5 | mod resume_test; -------------------------------------------------------------------------------- /docchi_archiver2/src/testing/resume_test.rs: -------------------------------------------------------------------------------- 1 | // use crate::{ArcResult, ArchiveOptions, resume_archive, read_archive_data}; 2 | // use crate::imp::create_archive_from_directory::CreateArchiveFromDirectory; 3 | // use anyhow::anyhow; 4 | // 5 | // //#[test] 6 | // fn resume_test() -> ArcResult<()>{ 7 | // let mut buf : Vec = Vec::new(); 8 | // if let CreateArchiveFromDirectory::WrittenSuccessfully(_a,_b) = 9 | // crate::imp::create_archive_from_directory::create_archive_from_directory( 10 | // "./src/json/general", &mut buf, |_| false, &ArchiveOptions::new())?{ 11 | // 12 | // let archive = read_archive_data(&mut buf.as_slice())?; 13 | // 14 | // resume_archive("./src/output/general/", &archive, true)?; 15 | // Ok(()) 16 | // } else{ 17 | // unreachable!() 18 | // } 19 | // } 20 | // 21 | -------------------------------------------------------------------------------- /docchi_compaction/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_compaction" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "A serializer which compresses integers" 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["serializer", "encode", "url"] 12 | 13 | [dependencies] 14 | bit-vec = "0.6.1" 15 | regex = "1" 16 | once_cell = "1.7.2" 17 | anyhow = "1.0.34" 18 | arrayvec = "0.5.2" 19 | with_capacity_safe = "0.4" 20 | -------------------------------------------------------------------------------- /docchi_compaction/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_compaction/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/decimal_lib.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn to_string(num : i128, dot : u8) -> String{ 2 | let mut s = num.to_string(); 3 | if dot == 0{ return s; } 4 | let sign; 5 | if num < 0{ 6 | sign = false; 7 | s.remove(0); 8 | } else{ 9 | sign = true; 10 | } 11 | let zeros = dot as isize - s.len() as isize; 12 | let mut result = String::new(); 13 | if 0 <= zeros{ 14 | result.push_str("0."); 15 | if 1 <= zeros { 16 | result.push_str(&String::from_utf8(vec!['0' as u8; zeros as usize]).unwrap()); 17 | } 18 | result.push_str(&s); 19 | } else{ 20 | result.push_str(&s); 21 | let index = s.len() - dot as usize; 22 | result.insert(index,'.'); 23 | } 24 | 25 | if sign == false{ 26 | result.insert(0, '-'); 27 | } 28 | 29 | return result; 30 | } 31 | 32 | pub(crate) fn to_f64(num : i128, dot : u8) -> f64{ 33 | (num as f64) / 10f64.powi(dot as i32) 34 | } -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/decode_from_slice.rs: -------------------------------------------------------------------------------- 1 | use crate::kval_enum::KVal; 2 | use crate::enc_dec::decode::decode; 3 | use crate::error::ComResult; 4 | 5 | /// &mut &vec may not be user-friendly. 6 | pub fn decode_from_slice(slice : &[u8]) -> ComResult<(Vec, usize)>{ 7 | let mut slice = slice; 8 | decode(&mut slice) 9 | } -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/encode_to_vec.rs: -------------------------------------------------------------------------------- 1 | use crate::kval_enum::KVal; 2 | use crate::enc_dec::encode::encode; 3 | use crate::error::ComResult; 4 | 5 | /// More user-friendly version of encode 6 | pub fn encode_to_vec(input : &[KVal]) -> ComResult>{ 7 | let mut vec : Vec = Vec::new(); 8 | let _ = encode(input, &mut vec)?; 9 | Ok(vec) 10 | } -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/kihon_from_tag.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, PartialEq)] 2 | pub(crate) enum KihonFromTag{ 3 | Null, 4 | Bit(bool), 5 | Bool(bool), 6 | Byte, 7 | Str16(u8), 8 | Int(u8), 9 | Float, 10 | Str256, 11 | Double, 12 | Decimal(u8), 13 | BigStr(u8), 14 | Binary(u8), 15 | Binary8(u8), 16 | Binary4(u8), 17 | Binary2(u8), 18 | Undefined(u8), 19 | } -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod encode; 2 | pub mod decode; 3 | mod tag_storage; 4 | pub mod signed_bytes; 5 | mod tag_reader; 6 | pub mod decimal_lib; 7 | pub mod var_int; 8 | pub mod kihon_from_tag; 9 | pub mod encode_to_vec; 10 | pub mod writer; 11 | pub mod reader; 12 | pub mod decode_from_slice; 13 | 14 | -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/signed_bytes.rs: -------------------------------------------------------------------------------- 1 | 2 | /// Return the number of bytes which can represents the val. 3 | /// 1. -128 ..= 127, 4 | /// 2. -32768..=32767... 5 | pub fn signed_bytes(val : i64) -> usize{ 6 | let mut val = if val < 0{ ((val + 1) * -1) as u64 } else{ val as u64 }; 7 | let mut size = 1; 8 | loop{ 9 | if val < 128{ return size; } 10 | val = val / 256; 11 | size += 1; 12 | } 13 | } 14 | 15 | /// Return the number of bytes which can represents the val. 16 | /// 1. -128 ..= 127, 17 | /// 2. -32768..=32767... 18 | pub fn signed_bytes128(val : i128) -> usize{ 19 | let mut val = if val < 0{ ((val + 1) * -1) as u128 } else{ val as u128 }; 20 | let mut size = 1; 21 | loop{ 22 | if val < 128{ return size; } 23 | val = val / 256; 24 | size += 1; 25 | } 26 | } -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/tag_storage.rs: -------------------------------------------------------------------------------- 1 | use bit_vec::BitVec; 2 | 3 | pub(crate) struct TagStorage{ 4 | pub(crate) vec : BitVec, 5 | 6 | } 7 | 8 | impl TagStorage{ 9 | pub(crate) fn new() -> TagStorage{ 10 | TagStorage{ vec : BitVec::new() } 11 | } 12 | ///n bitを追加。 13 | pub(crate) fn append(&mut self, val : u64, n : usize){ 14 | if n == 0{ return; } 15 | if 64 < n{ panic!("you can only append 64 bits at a time"); } 16 | 17 | //1bitずつ追加していく 18 | let mut filter : u64 = 2u64.pow(n as u32 - 1); 19 | loop{ 20 | let b = val & filter != 0; 21 | self.vec.push(b); 22 | filter = filter / 2; 23 | if filter == 0{ return; } 24 | } 25 | 26 | } 27 | 28 | pub(crate) fn to_vec(&self) -> Vec{ 29 | self.vec.to_bytes() 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /docchi_compaction/src/enc_dec/writer.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | use crate::error::ComResult; 3 | 4 | pub(crate) struct Writer<'a, T : Write>{ 5 | write : &'a mut T, 6 | len : usize, 7 | } 8 | 9 | impl<'a, T : Write> Writer<'a, T>{ 10 | pub(crate) fn new(write : &'a mut T) -> Self{ Self{ write, len : 0 } } 11 | pub(crate) fn write_byte(&mut self, byte : u8) -> ComResult{ 12 | self.write.write_all(&[byte])?; 13 | self.len += 1; 14 | Ok(1) 15 | } 16 | pub(crate) fn write(&mut self, bytes : &[u8]) -> ComResult{ 17 | self.write.write_all(bytes)?; 18 | self.len += bytes.len(); 19 | Ok(bytes.len()) 20 | } 21 | pub(crate) fn bytes_written(&self) -> usize{ self.len } 22 | 23 | //やる必要ある??? 24 | // pub fn flush(&mut self) -> Result<()>{ 25 | // self.write.flush()?; 26 | // Ok(()) 27 | // } 28 | } -------------------------------------------------------------------------------- /docchi_compaction/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny(unreachable_pub)] 2 | #![deny(unused_crate_dependencies)] 3 | 4 | 5 | /// Define the value type to serialize 6 | pub mod kval_enum; 7 | 8 | /// Details about the encoding and the decoding 9 | pub mod enc_dec; 10 | 11 | /// Convert bytes to the string which can be used as a part of URL and vice versa 12 | pub mod url_string; 13 | 14 | /// Compact integers and booleans 15 | pub mod basic_compaction; 16 | 17 | /// Compact strings if the string represents a number 18 | pub mod string_compaction; 19 | 20 | #[allow(unused_imports, dead_code)] 21 | #[cfg(test)] 22 | mod testing; 23 | pub mod error; 24 | 25 | 26 | pub use crate::enc_dec::encode::encode; 27 | pub use crate::enc_dec::decode::decode; 28 | pub use crate::enc_dec::encode_to_vec::encode_to_vec; 29 | pub use crate::enc_dec::decode_from_slice::decode_from_slice; 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /docchi_compaction/src/testing/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_enc_dec; 2 | mod test_string_compaction; -------------------------------------------------------------------------------- /docchi_compaction/src/url_string/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod b8s_and_b6s; 2 | pub mod char_and_b6; 3 | 4 | /// Convert bytes to the string which consists of A-Za-z0-9, hyphen and underscore 5 | pub fn get_url_string(bytes : &[u8]) -> String{ 6 | let b6s = self::b8s_and_b6s::to_b6s(bytes); 7 | self::char_and_b6::b6s_to_string(&b6s).unwrap() 8 | } 9 | 10 | /// Convert the string which consists of A-Za-z0-9, hyphen and underscore to bytes. 11 | pub fn get_bytes(url_string : &str) -> Option>{ 12 | let b6s = self::char_and_b6::string_to_b6s(url_string)?; 13 | Some(self::b8s_and_b6s::to_b8s(&b6s)) 14 | } -------------------------------------------------------------------------------- /docchi_compaction/src/仕様_old.txt: -------------------------------------------------------------------------------- 1 | 数値のバイト数をしっかり測ってキワキワまで小さくすることでデータを圧縮する。 2 | 3 | タグ部データ部と続く。データ部は1バイト区切り、タグ部は1bitずつ読む 4 | 1 続く1bitで0か1を表す 5 | 011 データ部1バイトで+127 to -128 を表す 6 | 0101 続く4bitでバイト数を表し、そのバイト数分データ部に文字列を形成。0-15バイトまでの文字列を表す。 7 | 0100_1 nullを表す 8 | 0100_01 続く1bitでboolを表す。動的型言語でbitと区別したい場合に使える。 9 | 0100_001 10進数を表す。続く4bitでバイト数を表し、1-16バイトの整数を表す。続く1バイトで小数点の位置を表現。255桁の小数が理論上可能であるが、16バイト整数は40桁ぐらいである。1ならば小数点1桁、2ならば2桁・・・と点が左にずれていく。 10 | 0011 続く3bitでバイト数を表し、1-8バイトの整数を表す。0-7を+1してバイト数を表す。 11 | 0010_1 データ部1バイトでバイト数を表し、その後のデータ部で実際の文字列を形成。255バイトまでの文字列を表す。 12 | 0010_01 8バイト浮動小数を表す 13 | 0010_001 続く3bitでバイト数を表し、データ部の続くそのバイトが表す数値の長さの文字列を表す。3bitは+1する。8バイトの表す約2000京バイト分の文字列が表せる 14 | 0010_0001 4バイト浮動小数を表す。静的型言語なら4byte整数にtruncateでもいいし、動的型言語でfloatが使われてるのを知らないから、なくてもよさそうなものだが、あってもよいだろう。 15 | 0001_1 undefined0を表す 16 | 0001_01 undefined1を表す 17 | 0001_0..1 undefined Nを表す。現状7まで 18 | 0000_11 blobを表す。続く3bitでバイト数を表し、データ部のbytesが表す数値の長さのバイト列を表す。3bitは+1する。8バイトの表す約2000京バイト分のバイト列が表せる 19 | 20 | 0,1を2bitで表せるので、任意桁数の数値とかも2進数に分解して倍のbit数をかければ表せるはずである。 21 | 22 | タグ部のはじまり 23 | 最初の1バイトは次の数値のバイト数を表す。続くバイトでタグ部のタグ数を表す。タグが全部終わったら、次のバイトからはデータ部である。 24 | 25 | -------------------------------------------------------------------------------- /docchi_core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_core" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "A statically typed data management language based on JSON5." 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["data","language"] 12 | 13 | [dependencies] 14 | docchi_json5 ={ path="../docchi_json5", version="0.8" } 15 | docchi_archiver2 = {path="../docchi_archiver2", version="0.8"} 16 | regex = "1.3.1" 17 | 18 | linked-hash-map = "0.5.2" 19 | fnv = "1.0.7" 20 | anyhow = "1.0.34" 21 | once_cell = "1.7.2" 22 | -------------------------------------------------------------------------------- /docchi_core/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_core/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_core/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) -------------------------------------------------------------------------------- /docchi_core/src/imp/intf/clist_iter_const.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | use crate::imp::intf::CItemPtr; 3 | use crate::imp::intf::clist::CListPtrIter; 4 | use crate::imp::intf::clist_const::CItemConst; 5 | 6 | unsafe impl<'a, V:From> Send for CListIterConst<'a, V>{} 7 | unsafe impl<'a, V:From> Sync for CListIterConst<'a, V>{} 8 | 9 | pub struct CListIterConst<'a, V : From>{ 10 | ptr : CListPtrIter, 11 | phantom : PhantomData<&'a i32>, 12 | } 13 | 14 | impl<'a, V : From> Iterator for CListIterConst<'a, V>{ 15 | type Item = CItemConst<'a, V>; 16 | 17 | fn next(&mut self) -> Option { 18 | self.ptr.next().map(|v| 19 | CItemConst::from_phantom(v, self.phantom)) 20 | } 21 | } 22 | 23 | impl<'a, V : From> CListIterConst<'a, V>{ 24 | pub fn new(ptr : CListPtrIter, _src : &'a T) -> CListIterConst<'a, V>{ 25 | CListIterConst{ ptr, phantom : PhantomData } 26 | } 27 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/intf/ctable_const.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | use std::ops::Deref; 3 | 4 | unsafe impl<'a, T> Send for CTableConst<'a, T>{} 5 | unsafe impl<'a, T> Sync for CTableConst<'a, T>{} 6 | #[derive(Debug)] 7 | pub struct CTableConst<'a, T>{ 8 | ptr : T, 9 | phantom : PhantomData<&'a i32>, 10 | } 11 | 12 | impl<'a, T> CTableConst<'a, T>{ 13 | pub fn new(ptr : T, _src : &'a U) -> CTableConst<'a, T>{ 14 | CTableConst{ ptr, phantom : PhantomData } 15 | } 16 | } 17 | 18 | impl<'a, T> Deref for CTableConst<'a, T>{ 19 | type Target = T; 20 | 21 | fn deref(&self) -> &Self::Target { 22 | &self.ptr 23 | } 24 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/intf/mod.rs: -------------------------------------------------------------------------------- 1 | pub use citem::CItemPtr; 2 | pub use clist::CListPtr; 3 | pub use clist_const::CItemConst; 4 | pub use clist_const::CListConst; 5 | pub use ctable_const::CTableConst; 6 | pub use mitem::MItemPtr; 7 | pub use mlist_const::MListConst; 8 | pub use mlist_mut::MItemMut; 9 | pub use mlist_mut::MListMut; 10 | //pub use c_qv_str::StrPtr as RustStrPtr; 11 | pub use mlist_ptr::MListPtr; 12 | pub use root::RootObjectPtr; 13 | pub use table::TablePtr; 14 | 15 | pub mod clist; 16 | pub mod mitem; 17 | pub mod mlist_ptr; 18 | pub mod ref_desc; 19 | pub mod citem; 20 | pub mod table; 21 | pub mod member_desc; 22 | pub mod root; 23 | pub mod mlist_mut; 24 | pub mod mlist_const; 25 | pub mod mlist_iter_mut; 26 | pub mod mlist_iter_const; 27 | pub mod clist_const; 28 | pub mod clist_iter_const; 29 | pub mod ctable_const; 30 | 31 | -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/get_id.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::json_to_rust::tmp::tmp_obj::IdValue; 2 | use docchi_json5::{JVal}; 3 | 4 | pub(crate) fn get_id(v : &JVal) -> Option { 5 | match v { 6 | JVal::String(s, _) => Some(IdValue::Str(s.to_string())), 7 | JVal::Double(d, _) => Some(IdValue::Num(*d as u64)), 8 | _ => None 9 | } 10 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/get_old.rs: -------------------------------------------------------------------------------- 1 | use docchi_json5::{JVal}; 2 | use crate::imp::json_to_rust::names::Names; 3 | use crate::error::CoreResult; 4 | use crate::imp::json_to_rust::json_name::{json_name, NameType}; 5 | use crate::imp::structs::var_type::VarType; 6 | use crate::imp::structs::util::hash_m::{HashS, HashSt}; 7 | 8 | pub(crate) fn get_old(array : &[JVal], names : &Names) -> CoreResult>{ 9 | let mut result : HashS = HashSt::with_capacity(array.len()); 10 | 11 | for item in array{ 12 | match item{ 13 | JVal::String(s, span) =>{ 14 | match json_name(s){ 15 | Some(NameType::Name(name, VarType::Normal)) =>{ 16 | result.insert(name); 17 | }, 18 | _ =>{ 19 | Err(format!("{} {} is not a valid simple name {}",span.line_str(), s, names))?; 20 | } 21 | } 22 | }, 23 | _ =>{ 24 | let span = item.span(); 25 | Err(format!(r#"{} {} old must be strings {}"#, span.line_str(), span.slice(), names))? 26 | } 27 | } 28 | } 29 | return Ok(result); 30 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/list/get_default.rs: -------------------------------------------------------------------------------- 1 | use docchi_json5::{JVal, Span}; 2 | use super::super::names::Names; 3 | use super::super::json_obj_to_rust::json_obj_to_rust; 4 | use crate::error::CoreResult; 5 | use crate::imp::structs::list_def_obj::ListDefObj; 6 | use linked_hash_map::LinkedHashMap; 7 | //use linked_hash_map::LinkedHashMap; 8 | 9 | pub(crate) fn get_default(array : &[JVal], span : &Span, names : &Names) -> CoreResult{ 10 | let error_message = r#"["Default", \{ default_obj \}] is valid"#; 11 | if array.len() != 1{ 12 | Err(format!(r#"{} {} {} {}"#, span.line_str(), span.slice(), error_message, names))? 13 | } 14 | return match &array[0]{ 15 | JVal::Map(map, _) =>{ 16 | Ok(get_default_obj(map, span, names)?) 17 | }, 18 | _ => Err(format!(r#"{} {} {} {}"#, span.line_str(), span.slice(), error_message, names))?, 19 | } 20 | } 21 | 22 | fn get_default_obj(map : &LinkedHashMap, span : &Span, names : &Names) -> CoreResult { 23 | let names = &names.append("default"); 24 | let obj = json_obj_to_rust(map, false, span, names)?; 25 | 26 | return obj.into_list_def_obj(); 27 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/list/get_list_items.rs: -------------------------------------------------------------------------------- 1 | use docchi_json5::{JVal, Span}; 2 | use crate::imp::json_to_rust::names::Names; 3 | use crate::error::CoreResult; 4 | use crate::imp::json_to_rust::json_obj_to_rust::json_obj_to_rust; 5 | use crate::imp::json_to_rust::tmp::tmp_obj::TmpObj; 6 | 7 | pub(crate) fn get_list_items(array : &[JVal], _span : &Span, names : &Names) -> CoreResult>{ 8 | let mut result : Vec = Vec::with_capacity(array.len()); 9 | for index in 0..array.len(){ 10 | let item = &array[index]; 11 | match item{ 12 | JVal::Map(map, span) =>{ 13 | result.push(json_obj_to_rust(map, false, span, names)?) 14 | }, 15 | _ =>{ 16 | Err(format!(r#"{} List's object sequence must not be interrupted {}"#, item.span().line_str(), names))? 17 | } 18 | } 19 | } 20 | return Ok(result); 21 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/list/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod list_attribute; 2 | pub(crate) mod json_list_to_rust; 3 | pub(crate) mod get_default; 4 | pub(crate) mod get_list_items; 5 | -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/names.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | pub(crate) struct Names<'a>{ 4 | pub(crate) name : &'a str, 5 | pub(crate) next : Option<&'a Names<'a>>, 6 | } 7 | 8 | impl<'a> Names<'a>{ 9 | pub(crate) fn to_string(&self) -> String{ 10 | let mut vec : Vec = vec![]; 11 | let mut cur = self; 12 | loop{ 13 | vec.push(cur.name.to_string()); 14 | if cur.next.is_none(){ 15 | break; 16 | } 17 | cur = cur.next.unwrap(); 18 | } 19 | vec.reverse(); 20 | vec.join(".") 21 | } 22 | 23 | pub(crate) fn append(&'a self, name : &'a str) -> Self{ 24 | Names::<'a>{ name, next : Some(self)} 25 | } 26 | 27 | pub(crate) fn new(name : &'a str) -> Self{ 28 | Names::<'a>{ name, next : None } 29 | } 30 | } 31 | 32 | impl<'a> Display for Names<'a>{ 33 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 34 | 35 | write!(f, "{}", self.to_string()) 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/roots/archive_src_dir.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | use crate::error::CoreResult; 3 | use std::path::Path; 4 | use docchi_archiver2::{ArchiveData, read_archive_data_from_directory}; 5 | use crate::JSON_ARC_OPT; 6 | 7 | pub fn archive_src_dir

, W : Write>(src_dir : P, writer : &mut W) -> CoreResult<()>{ 8 | let archive_data : ArchiveData<()> = read_archive_data_from_directory( 9 | src_dir, 10 | &*JSON_ARC_OPT, 11 | |_name, _dat| (), 12 | )?; 13 | Ok(docchi_archiver2::write_archive(&archive_data, writer)?) 14 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/roots/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod archive_data_to_root; 2 | pub(crate) mod archive_file_to_root; 3 | pub(crate) mod json_dir_to_root; 4 | pub(crate) mod json_file_to_rust; 5 | pub(crate) mod archive_src_dir; -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/set_empty_mils/initialize_empty_mils.rs: -------------------------------------------------------------------------------- 1 | // use crate::structs::{ListDefObj, MutListVal, ListDefValue}; 2 | // use crate::imp::structs::list_sab_value::ListSabValue; 3 | // use crate::{HashMt, HashM}; 4 | // 5 | // pub(crate) fn initialize_empty_mils(def : &ListDefObj) -> HashM{ 6 | // let mut hash : HashM = HashMt::new(); 7 | // for (name,_, def) in def.default(){ 8 | // match def{ 9 | // ListDefValue::MilDef(_d) =>{ 10 | // hash.insert(name.to_string(), ListSabValue::Mil(Some(MutListVal::crate_empty_list()))); 11 | // }, 12 | // _ =>{} 13 | // } 14 | // } 15 | // hash 16 | // } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/set_empty_mils/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod set_empty_mils_root; 2 | pub(crate) mod set_empty_mils; 3 | pub(crate) mod initialize_empty_mils; -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/set_empty_mils/set_empty_mils_root.rs: -------------------------------------------------------------------------------- 1 | // use crate::structs::{RootObject, RootValue, RootSabValue}; 2 | // use crate::imp::json_to_rust::set_empty_mils::set_empty_mils::set_empty_mils; 3 | // 4 | // pub(crate) fn set_empty_mils_root(root : &mut RootObject){ 5 | // 6 | // let (def, sabun, _) = root.def_and_mut_sab(); 7 | // for (name, (_id, val)) in def.def(){ 8 | // 9 | // //RootはOldでも値を入れざるを得ないので入れて良い 10 | // //なのでここではOldは無視 11 | // match val { 12 | // RootValue::Param(_, _) => {}, 13 | // RootValue::Table(_) =>{}, 14 | // RootValue::CList(_) =>{} 15 | // RootValue::MList(def) =>{ 16 | // match sabun.get_mut(name){ 17 | // Some(RootSabValue::Mut(Some(l))) =>{ 18 | // set_empty_mils(def.default(), l); 19 | // }, 20 | // _ => unreachable!(), 21 | // } 22 | // }, 23 | // } 24 | // } 25 | // } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/tmp/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod tmp_obj; 2 | pub(crate) mod tmp_list; 3 | -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/validation/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod validate_root; 2 | pub(crate) mod validate_list_item; 3 | pub(crate) mod validate_data; 4 | pub(crate) mod validate_list; 5 | pub(crate) mod validate_refs; 6 | pub(crate) mod validate_ref_def; 7 | pub(crate) mod validate_mut_list; 8 | pub(crate) mod validate_list_def; 9 | pub(crate) mod validate_old_def_mem; -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/validation/validate_data.rs: -------------------------------------------------------------------------------- 1 | //use crate::{HashM}; 2 | use crate::error::CoreResult; 3 | use crate::imp::json_to_rust::names::Names; 4 | use crate::imp::json_to_rust::validation::validate_list_item::validate_list_item; 5 | use crate::imp::json_to_rust::validation::validate_old_def_mem::validate_old_table_id; 6 | use crate::imp::structs::rust_list::ConstItem; 7 | use crate::imp::structs::root_obj::RootObject; 8 | use crate::imp::structs::list_def_obj::ListDefObj; 9 | use crate::imp::structs::util::hash_m::{HashS, HashM}; 10 | 11 | pub(crate) fn validate_table(def : &ListDefObj, data_map : &HashM, root : &RootObject, old : &HashS, 12 | can_use_old: bool, names : &Names) -> CoreResult<()>{ 13 | validate_old_table_id(old, data_map, names)?; 14 | 15 | for (name, val) in data_map{ 16 | //name==old なものがあっても別にかまわない。消すと互換性が崩れるだろう 17 | validate_list_item(def, val.values(), val.refs(), root, can_use_old, &names.append(name))? 18 | } 19 | return Ok(()); 20 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/validation/validate_list.rs: -------------------------------------------------------------------------------- 1 | use crate::error::CoreResult; 2 | use crate::imp::json_to_rust::names::Names; 3 | use crate::imp::json_to_rust::validation::validate_list_item::validate_list_item; 4 | use crate::imp::structs::rust_list::ConstItem; 5 | use crate::imp::structs::root_obj::RootObject; 6 | use crate::imp::structs::list_def_obj::ListDefObj; 7 | 8 | pub(crate) fn validate_const_list(def : &ListDefObj, data_vec : &Vec, root : &RootObject, can_use_old: bool, names : &Names) -> CoreResult<()>{ 9 | for (idx, val) in data_vec.iter().enumerate(){ 10 | let idx = format!("#{}", idx); 11 | let names = &names.append(&idx); 12 | validate_list_item(def, val.values(), val.refs(), root, can_use_old, names)?; 13 | } 14 | return Ok(()); 15 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/validation/validate_mut_list.rs: -------------------------------------------------------------------------------- 1 | use crate::error::CoreResult; 2 | use crate::imp::json_to_rust::names::Names; 3 | use crate::imp::json_to_rust::validation::validate_list_item::validate_list_item; 4 | use crate::imp::structs::root_obj::RootObject; 5 | use crate::imp::structs::list_def_obj::ListDefObj; 6 | use crate::imp::structs::rust_list::MutItem; 7 | use crate::imp::structs::linked_m::LinkedMap; 8 | 9 | pub(crate) fn validate_mut_list(def : &ListDefObj, map : &LinkedMap, root : &RootObject, 10 | can_use_old: bool, names : &Names) -> CoreResult<()>{ 11 | for (idx, val) in map{ 12 | let idx = format!("#{}", idx); 13 | let names = &names.append(&idx); 14 | validate_list_item(def, val.values(), val.refs(), root, can_use_old, names)?; 15 | } 16 | return Ok(()); 17 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/json_to_rust/validation/validate_ref_def.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::json_to_rust::names::Names; 2 | use crate::error::CoreResult; 3 | use crate::imp::json_to_rust::validation::validate_old_def_mem::validate_old_ref_def; 4 | use crate::imp::structs::ref_def_obj::RefDefObj; 5 | use crate::imp::structs::qv::Qv; 6 | 7 | 8 | pub(crate) fn validate_ref_def(def : &RefDefObj, names : &Names) -> CoreResult<()> { 9 | if def.is_enum() { 10 | for (_, _, v) in def.refs() { 11 | match v.value() { 12 | Qv::Null => {}, 13 | _ => Err(format!("{} all default members of Enum must be null", names))?, 14 | } 15 | } 16 | } 17 | if def.is_enum() { 18 | validate_old_ref_def(def.old(), def.refs(), &names.append("Enum"))?; 19 | } else { 20 | validate_old_ref_def(def.old(), def.refs(), &names.append("Ref"))?; 21 | } 22 | 23 | Ok(()) 24 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod json_to_rust; 2 | pub(crate) mod rust_to_json; 3 | pub(crate) mod version_adjuster; 4 | pub(crate) mod structs; 5 | 6 | ///This module contains low-level accessors. 7 | /// They are intended to be used by generated codes, not humans. 8 | pub mod intf; -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/get_param.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::rust_to_json::rust_array_to_json::rust_array_to_json; 2 | use crate::imp::structs::qv::Qv; 3 | use crate::imp::structs::my_json::Value; 4 | use crate::imp::structs::rust_param::RustParam; 5 | 6 | pub(crate) fn get_param(v : &RustParam) -> Value{ 7 | let r = match v{ 8 | RustParam::Bool(b) => to(b, "Bool",|b| Value::Bool(*b)), 9 | RustParam::String(s) => to(s, "Str", |s| Value::String(s.str().to_string())), 10 | RustParam::Float(n)=> to(n, "Float", 11 | |n| Value::Array(vec![Value::String("Float".to_string()), Value::Number(*n)])), 12 | RustParam::Int(n)=> to(n, "Int", |n| Value::Number(*n as f64)), 13 | _ =>{ 14 | let (array, at) = v.to_rust_array().unwrap(); 15 | rust_array_to_json(&array, &at) 16 | }, 17 | }; 18 | return r; 19 | } 20 | 21 | fn to(qv : &Qv, type_name : &str, f : impl Fn(&T)->Value) -> Value{ 22 | match qv{ 23 | Qv::Val(v) => f(v), 24 | Qv::Null => Value::Array(vec![Value::String(type_name.to_string()), Value::Null]), 25 | Qv::Undefined => Value::Array(vec![Value::String(type_name.to_string()), Value::Undefined]), 26 | } 27 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/inner_mut_def_to_json.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::rust_to_json::list::default_to_json::default_to_json; 2 | use crate::imp::structs::my_json::Value; 3 | use crate::imp::structs::mut_list_def::MutListDef; 4 | 5 | pub(crate) fn inner_mut_def_to_json(d : &MutListDef) -> Value{ 6 | let mut result : Vec = Vec::new(); 7 | 8 | result.push(Value::String("MilDef".to_string())); 9 | // if d.compatible().len() != 0{ 10 | // result.push(string_set_to_json("Compatible", &btree_set(d.compatible()))); 11 | // } 12 | 13 | result.push(Value::Array(vec![default_to_json(d.default())])); 14 | 15 | 16 | return Value::Array(result); 17 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/list_type_to_string.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs::list_type::ListType; 2 | 3 | pub(crate) fn list_type_to_string(l : &ListType) -> String{ 4 | let s = match l{ 5 | ListType::Table => "Table", 6 | ListType::CList => "CList", 7 | ListType::MList => "MList", 8 | //ListType::InnerData => "InnerData", 9 | ListType::Cil => "Cil", 10 | ListType::Mil => "Mil", 11 | //ListType::InnderDataDef => "InnerDataDef", 12 | ListType::CilDef => "CilDef", 13 | //ListType::InnerMutDef => if has_item{ "__InnerViolatedListDef" } else{ "InnerMutDef" }, 14 | }; 15 | s.to_string() 16 | 17 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod tmp_list_to_json; 2 | pub(crate) mod list_type_to_string; 3 | pub(crate) mod default_to_json; 4 | pub(crate) mod tmp_json_list; 5 | pub(crate) mod value_map_to_json; 6 | pub(crate) mod ref_def_obj_to_json; 7 | pub(crate) mod tmp_obj_to_json; 8 | pub(crate) mod tmp_refs_to_json; 9 | pub(crate) mod inner_mut_def_to_json; -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/ref_def_obj_to_json.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | use crate::imp::structs::ref_def_obj::RefDefObj; 3 | use crate::imp::structs::qv::Qv; 4 | use crate::imp::structs::var_type::VarType; 5 | use crate::imp::structs::my_json::Value; 6 | 7 | pub(crate) fn ref_def_obj_to_json(obj : &RefDefObj) -> BTreeMap{ 8 | let mut result : BTreeMap = BTreeMap::new(); 9 | 10 | for (key,_, value) in obj.refs() { 11 | let (key, value) = reconstruct_ref_value(key, value.value(), value.var_type()); 12 | result.insert(key, value); 13 | } 14 | 15 | return result; 16 | } 17 | 18 | pub(crate) fn reconstruct_ref_value(name : &String, value : &Qv, value_type : VarType) -> (String, Value){ 19 | (format!("{}{}", name.to_string(), value_type.to_suffix()), match value{ 20 | Qv::Val(v) => Value::String(v.to_string()), 21 | Qv::Null => Value::Null, 22 | Qv::Undefined => Value::Undefined, 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/tmp_refs_to_json.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::rust_to_json::list::tmp_json_list::TmpJsonRefs; 2 | use crate::imp::rust_to_json::list::ref_def_obj_to_json::reconstruct_ref_value; 3 | use std::collections::BTreeMap; 4 | use crate::imp::rust_to_json::string_set_to_json::string_set_to_json_short; 5 | use crate::imp::structs::my_json::Value; 6 | 7 | pub(crate) fn tmp_refs_to_json(refs : &TmpJsonRefs) -> Value{ 8 | let mut result :BTreeMap = BTreeMap::new(); 9 | for (name, val) in &refs.map{ 10 | let (name, val) = reconstruct_ref_value(name, val.value(), val.var_type()); 11 | result.insert(name, val); 12 | } 13 | 14 | if let Some(old) = &refs.old{ 15 | result.insert("Old".to_string(), string_set_to_json_short(old)); 16 | } 17 | 18 | return Value::Map(result); 19 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/list/value_map_to_json.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{BTreeMap}; 2 | use crate::imp::rust_to_json::rust_value_to_json_value::rust_value_to_json_value; 3 | use crate::imp::structs::rust_value::RustValue; 4 | use crate::imp::structs::my_json::Value; 5 | 6 | pub(crate) fn value_map_to_json(map : &BTreeMap) -> BTreeMap{ 7 | let mut result = BTreeMap::new(); 8 | 9 | for (name,val) in map{ 10 | let (name, val) = rust_value_to_json_value(val, name); 11 | result.insert(name, val); 12 | } 13 | 14 | return result; 15 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod root_to_json; 2 | pub(crate) mod rust_value_to_json_value; 3 | pub(crate) mod rust_array_to_json; 4 | pub(crate) mod list; 5 | pub(crate) mod get_param; 6 | pub(crate) mod string_set_to_json; 7 | pub(crate) mod name_with_suffix; 8 | -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/name_with_suffix.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs::var_type::VarType; 2 | 3 | pub(crate) fn name_with_suffix(name : &str, vt : VarType) -> String{ 4 | format!("{}{}", name, vt.to_suffix()) 5 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/rust_to_json/string_set_to_json.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{ BTreeSet}; 2 | use crate::imp::structs::my_json::Value; 3 | 4 | ///long : [tag, "hoge", "huga"] short : ["hoge", "huga"] 5 | pub(crate) fn string_set_to_json_short(s : &BTreeSet) -> Value{ 6 | Value::Array(s.iter().map(|s| Value::String(s.to_string())).collect()) 7 | } 8 | 9 | ///[tag, "hoge", "huga"] 10 | pub(crate) fn string_set_to_json(tag : &str, s : &BTreeSet) -> Value{ 11 | let mut vec = vec![Value::String(tag.to_string())]; 12 | vec.extend(s.iter().map(|s| Value::String(s.to_string()))); 13 | Value::Array(vec) 14 | } 15 | 16 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/array_type.rs: -------------------------------------------------------------------------------- 1 | 2 | #[derive(Debug, Clone, PartialEq)] 3 | pub(crate) enum ArrayType{ 4 | Float, 5 | Int, 6 | Binary, 7 | } 8 | 9 | impl ArrayType{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/docchi_archive.rs: -------------------------------------------------------------------------------- 1 | use crate::structs::{RootObject, RootValue, RootSabValue}; 2 | use crate::error::CoreResult; 3 | use docchi_archiver2::{ArchiveData, write_archive}; 4 | use std::io::Write; 5 | use crate::imp::json_to_rust::roots::archive_data_to_root::archive_to_root; 6 | 7 | pub struct DocchiArchive { 8 | pub(crate) data : ArchiveData> 9 | } 10 | 11 | impl DocchiArchive { 12 | pub(crate) fn new(data : ArchiveData>) -> DocchiArchive { 13 | DocchiArchive { data } 14 | } 15 | pub fn hash(&self) -> u128{ 16 | self.data.hash() 17 | } 18 | pub fn write_archive(&self, writer : &mut W) -> CoreResult<()>{ 19 | Ok(write_archive(&self.data, writer)?) 20 | } 21 | pub fn into_root(self, validation : bool) -> CoreResult{ 22 | archive_to_root(self, validation) 23 | } 24 | } 25 | 26 | pub(crate) enum ArchivingItem{ 27 | Root(RootObject), 28 | Item((String, RootValue, Option)), 29 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/json_file.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | use crate::imp::structs::my_json::Value; 3 | 4 | 5 | #[derive(Debug)] 6 | pub struct JsonFileImpl{ 7 | pub filename_without_ext : String, 8 | pub json : String, 9 | } 10 | 11 | impl JsonFile for &JsonFileImpl{ 12 | fn filename_without_ext(&self) -> &str { 13 | &self.filename_without_ext 14 | } 15 | 16 | fn json(&self) -> &str { 17 | &self.json 18 | } 19 | } 20 | 21 | pub trait JsonFile{ 22 | fn filename_without_ext(&self) -> &str; 23 | fn json(&self) -> &str; 24 | } 25 | 26 | /// (filename_without_ext, json) 27 | impl JsonFile for (&str, &str){ 28 | fn filename_without_ext(&self) -> &str { 29 | self.0 30 | } 31 | 32 | fn json(&self) -> &str { 33 | self.1 34 | } 35 | } 36 | 37 | #[derive(Debug)] 38 | pub struct JsonDir(pub BTreeMap); 39 | 40 | impl JsonDir{ 41 | pub fn to_string(&self) -> String{ 42 | let mut result = String::new(); 43 | let map = &self.0; 44 | for (name, value) in map{ 45 | 46 | result.push_str(&format!("{} : {}\n",name, value.to_string_pretty())); 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/list_type.rs: -------------------------------------------------------------------------------- 1 | pub(crate) enum ListType{ 2 | Table, 3 | CList, 4 | MList, //InnerData, 5 | Cil, 6 | Mil, //InnderDataDef, 7 | CilDef, //InnerMutDef, 8 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod linked_m; 2 | pub(crate) mod param_type; 3 | pub(crate) mod mut_list_def; 4 | pub(crate) mod list_def_obj; 5 | pub(crate) mod array_type; 6 | pub(crate) mod var_type; 7 | pub(crate) mod rust_value; 8 | pub(crate) mod qv; 9 | pub(crate) mod rust_list; 10 | pub(crate) mod ref_def_obj; 11 | 12 | pub(crate) mod ref_value; 13 | pub(crate) mod json_file; 14 | pub(crate) mod root_obj; 15 | pub(crate) mod my_json; 16 | pub(crate) mod rust_param; 17 | pub(crate) mod rust_array; 18 | pub(crate) mod list_type; 19 | pub(crate) mod rust_string; 20 | pub(crate) mod root_value; 21 | pub(crate) mod list_value; 22 | 23 | pub(crate) mod util; 24 | pub(crate) mod meta_table; 25 | pub(crate) mod list_sab_value; 26 | pub(crate) mod root_sab_value; 27 | pub(crate) mod root_def_obj; 28 | pub(crate) mod linked_map_unsafe_iter; 29 | pub(crate) mod linked_map_iter; 30 | pub(crate) mod linked_map_iter_mut; 31 | pub(crate) mod null_or; 32 | 33 | pub(crate) mod docchi_archive; 34 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/mut_list_def.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs::list_def_obj::ListDefObj; 2 | 3 | #[derive(Debug, Clone, PartialEq)] 4 | pub struct MutListDef { 5 | default: Box, 6 | undefiable: bool, 7 | //compatible : Box>, 8 | } 9 | 10 | impl MutListDef { 11 | pub(crate) fn new(default: ListDefObj, undefiable: bool) -> MutListDef { 12 | MutListDef { default: Box::new(default), undefiable } 13 | } 14 | pub fn default(&self) -> &ListDefObj{ self.default.as_ref() } 15 | pub fn undefiable(&self) -> bool{ self.undefiable } 16 | //pub(crate) fn compatible(&self) -> &HashS{ self.compatible.as_ref() } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/root_def_obj.rs: -------------------------------------------------------------------------------- 1 | use crate::{HashM}; 2 | use crate::imp::structs::root_value::RootValue; 3 | 4 | #[derive(Debug, Clone, PartialEq)] 5 | pub struct RootDefObj{ 6 | def : HashM, 7 | } 8 | 9 | impl RootDefObj{ 10 | pub fn new(def : HashM) -> RootDefObj{ 11 | RootDefObj{ def } 12 | } 13 | pub fn def(&self) -> &HashM{ &self.def } 14 | ///DefObjは構築後は変更されないのだが、行きがかり上構築時にmodifyが必要になってしまった 15 | pub(crate) fn def_mut(&mut self) -> &mut HashM{ &mut self.def } 16 | pub fn get(&self, name : &str) -> Option<&RootValue>{ self.def.get(name).map(|(_,v)|v) } 17 | pub fn contains_key(&self, name : &str) -> bool{ self.def.contains_key(name) } 18 | pub fn len(&self) -> usize{ self.def.len() } 19 | //pub fn deconstruct(self) -> HashM{ self.def } 20 | } 21 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/root_value.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs::rust_param::RustParam; 2 | use crate::imp::structs::var_type::VarType; 3 | use crate::imp::structs::rust_list::{ConstTable, ConstList}; 4 | use crate::imp::structs::rust_value::RustValue; 5 | use crate::imp::structs::mut_list_def::MutListDef; 6 | use crate::error::CoreResult; 7 | use crate::imp::structs::root_sab_value::RootSabValue; 8 | 9 | #[derive(Debug, Clone, PartialEq)] 10 | pub enum RootValue{ 11 | Param(RustParam, VarType), 12 | Table(ConstTable), 13 | CList(ConstList), 14 | MList(MutListDef), 15 | } 16 | 17 | impl RootValue{ 18 | 19 | pub fn into_rust_value(self, sab : RootSabValue) -> CoreResult{ 20 | match self{ 21 | RootValue::Param(p,v) => Ok(RustValue::Param(p,v)), 22 | RootValue::Table(d) => Ok(RustValue::Table(d)), 23 | RootValue::CList(d) => Ok(RustValue::CList(d)), 24 | RootValue::MList(d) =>{ 25 | if let RootSabValue::Mut(m) = sab { 26 | Ok(RustValue::MList((d, m))) 27 | } else{ 28 | Err("unmatched Mut List")? 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/util/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod hash_m; 2 | pub(crate) mod set_sabun; 3 | pub(crate) mod identity_equal_trait; -------------------------------------------------------------------------------- /docchi_core/src/imp/structs/util/set_sabun.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs::rust_param::RustParam; 2 | use crate::imp::structs::var_type::VarType; 3 | 4 | pub(crate ) fn verify_set_sabun(p : &RustParam, vt : &VarType, sab : &RustParam) -> Result<(), SetSabunError>{ 5 | if p.acceptable(sab) == false{ 6 | return Err(SetSabunError::ParamTypeMismatch); 7 | } 8 | if vt.acceptable( &sab.qv_type()) == false{ 9 | return Err(SetSabunError::QvTypeMismatch); 10 | } 11 | return Ok(()); 12 | } 13 | 14 | pub enum SetSabunError{ 15 | ParamNotFound, ParamTypeMismatch, QvTypeMismatch 16 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/version_adjuster/adjust_mut_list_item_ref.rs: -------------------------------------------------------------------------------- 1 | //use crate::{HashM, HashMt}; 2 | use crate::error::CoreResult; 3 | use crate::imp::json_to_rust::names::Names; 4 | use crate::imp::structs::ref_def_obj::RefDefObj; 5 | use crate::imp::structs::ref_value::RefSabValue; 6 | use crate::imp::structs::qv::Qv; 7 | use crate::imp::structs::util::hash_m::{HashM, HashMt}; 8 | 9 | pub(crate) fn adjust_mut_list_item_ref(def : &RefDefObj, old_ref : &mut HashM, _names : &Names) -> CoreResult>{ 10 | 11 | //事前に大きさが決定できないが、refのusecaseだとundefinedは少なく、default値のままが多いと思うので、sabunのlenを使う 12 | let mut result : HashM = HashMt::with_capacity(old_ref.len()); 13 | 14 | for (def_key,_, def_v) in def.refs(){ 15 | let sabun_v = if let Some(v) = old_ref.remove(def_key){ v } else { 16 | if def_v.var_type().undefiable(){ 17 | RefSabValue::new(Qv::Undefined) 18 | } else{ 19 | continue; 20 | } 21 | }; 22 | result.insert(def_key.to_string(), sabun_v); 23 | } 24 | Ok(result) 25 | } -------------------------------------------------------------------------------- /docchi_core/src/imp/version_adjuster/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod version_adjuster; 2 | pub(crate) mod adjust_mut_list; 3 | pub(crate) mod adjust_mut_list_item_sabun; 4 | pub(crate) mod adjust_mut_list_item_ref; -------------------------------------------------------------------------------- /docchi_core/src/json_dir/json_dir_siyou.txt: -------------------------------------------------------------------------------- 1 | ディレクトリを指定すると、全部の拡張子"json5"のファイルが読み込まれて、解析される。 2 | ディレクトリの下のディレクトリに置いてあるファイルは解析しない。ファイル名は直接メンバ名に対応するので、メンバ名に使えない名前は使用不能になる。 3 | ルートオブジェクトのファイル名はroot.json5である。それ以外の名前は認められない。 -------------------------------------------------------------------------------- /docchi_core/src/json_dir/json_siyou/someData.json5: -------------------------------------------------------------------------------- 1 | [ 2 | "Table", 3 | ["Default", { s : "", n : 0.0, Ref : { unkoList : ""}}], 4 | { 5 | ID : "a1ban", 6 | Ref : { unkoList : "first" }, 7 | }, 8 | { 9 | ID: "a2ban", 10 | s: "hugahuga", 11 | n: 30.08, 12 | Ref: { 13 | unkoList: "second" 14 | }, 15 | } 16 | ] -------------------------------------------------------------------------------- /docchi_core/src/json_dir/json_siyou/someStr.json5: -------------------------------------------------------------------------------- 1 | "some string" -------------------------------------------------------------------------------- /docchi_core/src/old/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate ) mod json_siyou_old; -------------------------------------------------------------------------------- /docchi_core/src/old/objectからobjectを生やすか.txt: -------------------------------------------------------------------------------- 1 | //List以外のObjectを作る意味がさっぱりないじゃないですか。 2 | //一応Type指定することで、同一の型だった場合に同じようにアクセスできるtraitみたいな機能を用意するべきだろうか。 3 | //概念整理のためにObjectを分けるというのは考え方ではあるけど、それによって互換性は破壊されてしまう。 4 | 5 | //で、そうした場合に、undefinedを用意する必然性は確保できるだろうか。 6 | //objectをundefinedにした場合、うれしいことは、undefinedだった場合にobjectの中身を計算して別のものに変えられること。 7 | //ダメな点は、オブジェクトの中身にアクセスしようとしたときに何を出せばいいのかわからないこと。 8 | 9 | //undefinedのオブジェクト自体はundefinedにはならないけど、中身のundefined可能なメンバはすべてundefinedになる、という折衷案が良さそうに思う。 10 | //objectをundefinedにするのはやっぱり良くないと思う。オブジェクトの中のundefined可能でない部分をどう考えるか不明になるし。 11 | 12 | 結局objectの中にobjectを用意する必然性が分からないままだ。概念整理にはなるかもしれないけど、そもそもそんな機能は必要ないという説も濃厚である。 13 | 14 | Includeを行うためには必須の機能であり、Includeは必須の機能なので、やはり必須の機能である可能性は高そうだが・・・ 15 | 16 | いったんObjectの中にObjectを作る機能はなしでいこうかと思う。必要である理由がさっぱりわからないわりに作るのが大変でファイルの見通しも悪くなると思う。 17 | トップのオブジェクトに全部の制御情報がはいり、下にはひたすらListが生えるというのがわかりやすい形になると思う。ListIDの一元管理の意味でもその方がキレイだ。 18 | 19 | 結局オブジェクトのメンバをいくつかまとめて一つのオブジェクトにして、オブジェクトから生やすという行動をとった時、名前変更のトラッキングでは間に合わないし 20 | 根本的に圧倒的な破壊的変更になってバージョン感で互換性を保つ方法がなくなってしまう。バージョン間の互換性がなくなるすべての変更を避ける必要があるというのが 21 | このシステムの根っこなので、これは受け入れられない。 -------------------------------------------------------------------------------- /docchi_core/src/old/renameに関して.txt: -------------------------------------------------------------------------------- 1 | RenameとかRedefineとかいろいろややこしいことになっている。 2 | 可読性を下げたくないから、jsonファイル内ではRenameは無効。古い名前を使ってる場合容赦なくエラーにする。 3 | バージョン間のアジャスト時にしかRenameは使わない -------------------------------------------------------------------------------- /docchi_core/src/old/なぜデフォルト値が必要なのか.txt: -------------------------------------------------------------------------------- 1 | デフォルト値の必要性の最たるものは、既存のファイルにないメンバが加わった時、デフォルト値が代入される仕組みにある。 2 | デフォルト値から変化のないメンバは記述しなくて良い、というルールにすることで、デフォルト値から変化がないメンバはデータを節約でき、 3 | またデフォルト値が変更された場合自動的に旧バージョンのデータも置き換わる。これはいいことだと思っている。 4 | 記述しなくてもエラーにならないのは問題ではないか、という説もある。書き忘れていても誰も文句を言わなくなってしまう。 5 | 特にRefである。RefはNull以外は書かなきゃいけないルールでいいのではないかと思ってる。 6 | ただ、書くのがめんどくさいのでデフォルトをNullにしてしまうというナッジが行われる可能性もある。 7 | ただ、リストのすべてのメンバがデフォルトで何かを参照するというのは不自然なように思う。 8 | しかし、他と統一性をもたせたいので、デフォルト値でないもの以外書かなくて良いを貫いても良さそうだ。結局視認性が高いことがミスを防ぎ、ノイズや冗長な繰り返しはミスの元にしかならない。 -------------------------------------------------------------------------------- /docchi_core/src/old/ロードマップ.txt: -------------------------------------------------------------------------------- 1 | deeta 2 | dielta 3 | /adjust_list_item_valuesとadjust_root_objを書いて、adjust_listを書けばOKではないかと思う 4 | 5 | バージョンのアジャスタを作る 6 | jsonからRustのアクセサ生成 7 | 8 | 差分バイナリ生成 9 | 差分の作り方を整えて差分ベースのデータ保存システム完成 -------------------------------------------------------------------------------- /docchi_core/src/testing/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_linked_m; 2 | mod initialize_performance_test; 3 | mod json_to_rust_and_json; 4 | mod test_version_adjuster; 5 | mod check_type_size; -------------------------------------------------------------------------------- /docchi_diff/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_diff" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "Calculates Docchi Diff." 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["data","diff"] 12 | 13 | [dependencies] 14 | docchi_core = { path="../docchi_core", version="0.8" } 15 | docchi_compaction = {path="../docchi_compaction", version="0.8"} 16 | 17 | anyhow = "1.0.34" 18 | with_capacity_safe = "0.4" 19 | -------------------------------------------------------------------------------- /docchi_diff/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_diff/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_diff/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/apply_params.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::HashM; 2 | use docchi_core::structs::{ListSabValue, MetaTable, RustParam}; 3 | use crate::diff_error::DiffError; 4 | 5 | pub(crate) fn apply_params(params : Vec<(usize, RustParam)>, meta : &MetaTable, 6 | r : &mut HashM) -> Result<(), DiffError>{ 7 | 8 | for (id,param)in params{ 9 | let (key, _) = if let Some(v) = meta.get(id){ v } else{ 10 | Err("meta is invalid apply_list_diff:new_item")? 11 | }; 12 | r.insert(key.to_string(), ListSabValue::Param(param)); 13 | } 14 | return Ok(()); 15 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/apply_refs.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{Qv, MetaTable, RefSabValue}; 2 | use docchi_core::HashM; 3 | use crate::diff_error::DiffError; 4 | 5 | pub(crate) fn apply_refs(refs : Vec<(usize, Qv)>, meta : &MetaTable, 6 | r : &mut HashM) -> Result<(), DiffError>{ 7 | 8 | for (id, qv) in refs{ 9 | let (key, _) = if let Some(v) = meta.get(id){ v } else{ 10 | Err("meta is invalid apply_refs")? 11 | }; 12 | r.insert(key.to_string(), RefSabValue::new(qv)); 13 | } 14 | Ok(()) 15 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/diff_to_new_list.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs_read::ListDiffR; 2 | use crate::diff_error::DiffError; 3 | use docchi_core::structs::{MutListVal, LinkedMap, MutItem, MetaTables}; 4 | use crate::imp::apply::apply_list_diff::apply_list_diff; 5 | 6 | pub(crate) fn diff_to_new_list(diff : ListDiffR, meta : &MetaTables) -> Result{ 7 | let mut map : LinkedMap = LinkedMap::new(); 8 | 9 | apply_list_diff(&mut map, diff, meta)?; 10 | 11 | Ok(MutListVal::new(map)) 12 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod apply_root_diff; 2 | pub(crate) mod apply_list_diff; 3 | pub(crate) mod diff_to_new_list; 4 | pub(crate) mod apply_params; 5 | pub(crate) mod apply_lists; 6 | pub(crate) mod modify_item_from_diff; 7 | pub(crate) mod apply_refs; 8 | pub(crate) mod new_item_from_diff; -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/modify_item_from_diff.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs_read::ListItemDiffR; 2 | use docchi_core::structs::{MetaTables, MutItem}; 3 | use crate::diff_error::DiffError; 4 | use crate::imp::apply::apply_params::apply_params; 5 | use crate::imp::apply::apply_lists::apply_lists; 6 | use crate::imp::apply::apply_refs::apply_refs; 7 | 8 | pub(crate) fn modify_item_from_diff(item : &mut MutItem, diff : ListItemDiffR, 9 | meta : &MetaTables) -> Result<(), DiffError>{ 10 | let (params, lists, refs) = diff.deconstruct(); 11 | let values = item.values_mut(); 12 | apply_params(params, meta.items(), values)?; 13 | apply_lists(lists, meta.items(), values)?; 14 | 15 | let ref_hash = item.refs_mut(); 16 | apply_refs(refs, meta.refs(), ref_hash)?; 17 | 18 | Ok(()) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply/new_item_from_diff.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::structs_read::ListItemDiffR; 2 | use docchi_core::structs::{MetaTables, MutItem, ListSabValue, RefSabValue}; 3 | use crate::diff_error::DiffError; 4 | use docchi_core::{HashM, HashMt}; 5 | use crate::imp::apply::apply_params::apply_params; 6 | use crate::imp::apply::apply_lists::apply_lists; 7 | use crate::imp::apply::apply_refs::apply_refs; 8 | 9 | pub(crate) fn new_item_from_diff(diff : ListItemDiffR, 10 | meta : &MetaTables) -> Result{ 11 | let (params, lists, refs) = diff.deconstruct(); 12 | let mut values : HashM = HashMt::with_capacity(params.len()); 13 | apply_params(params, meta.items(), &mut values)?; 14 | apply_lists(lists, meta.items(), &mut values)?; 15 | 16 | let mut ref_hash : HashM = HashMt::with_capacity(refs.len()); 17 | apply_refs(refs, meta.refs(), &mut ref_hash)?; 18 | 19 | Ok(MutItem::new(values, ref_hash)) 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /docchi_diff/src/imp/apply_diff.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{RootObject, MetaTable}; 2 | use crate::imp::read::reader::Reader; 3 | use crate::imp::read::read_root::read_root; 4 | use crate::imp::apply::apply_root_diff::apply_root_diff; 5 | use std::io::Read; 6 | use docchi_compaction::enc_dec::decode::decode; 7 | use crate::imp::structs_read::RootDiffR; 8 | use docchi_compaction::kval_enum::KVal; 9 | use crate::DiffResult; 10 | 11 | /// Applies diff data and restores the object 12 | pub fn apply_diff(root : &mut RootObject, diff : &mut R) -> DiffResult<()>{ 13 | let (diff, _size) = decode(diff)?; 14 | let mut reader = Reader::new(diff); 15 | let diff = read_root(&mut reader, root.meta_table())?; 16 | apply_root_diff(root, diff)?; 17 | Ok(()) 18 | } 19 | 20 | pub fn get_root_diff_r(kvals : Vec, meta_table : &MetaTable) -> DiffResult{ 21 | let mut reader = Reader::new(kvals); 22 | Ok(read_root(&mut reader, meta_table)?) 23 | } 24 | 25 | pub fn apply_root_diff_r(root : &mut RootObject, diff : RootDiffR) -> DiffResult<()>{ 26 | apply_root_diff(root, diff) 27 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod structs_write; 2 | pub(crate) mod apply; 3 | pub(crate) mod write; 4 | pub(crate) mod prepare; 5 | pub(crate) mod read; 6 | pub(crate) mod structs_read; 7 | pub(crate) mod get_diff; 8 | pub(crate) mod apply_diff; 9 | -------------------------------------------------------------------------------- /docchi_diff/src/imp/prepare/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod get_mlist_diff; 2 | pub(crate) mod get_root_diff; 3 | pub(crate) mod compare_items; 4 | pub(crate) mod new_item; 5 | pub(crate) mod new_list; 6 | -------------------------------------------------------------------------------- /docchi_diff/src/imp/prepare/new_list.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{MutListVal, ListDefObj, MetaTables}; 2 | use crate::imp::structs_write::{ListDiffW, ListItemDiffEnumW, BS}; 3 | use crate::imp::prepare::new_item::new_item; 4 | 5 | pub(crate) fn new_list<'a, 'b>(mil : &'a MutListVal, def : &'a ListDefObj, meta : &'a MetaTables) -> ListDiffW<'a>{ 6 | let mut result : Vec<(u64, ListItemDiffEnumW)> = Vec::new(); 7 | 8 | let mut prev_id : Option = None; 9 | for (&id, item) in mil.list() { 10 | result.push((id, ListItemDiffEnumW::Create( 11 | BS{ prev_id, diff : new_item(item, def, meta) }))); 12 | prev_id = Some(id); 13 | } 14 | 15 | ListDiffW::new(result, meta, mil.list().next_id()) 16 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/read/get_null.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{ParamType, RustParam, Qv}; 2 | 3 | pub(crate) fn get_null(pt : ParamType) -> RustParam{ 4 | match pt { 5 | ParamType::Bool => { RustParam::Bool(Qv::Null) } 6 | ParamType::Int => { RustParam::Int(Qv::Null) } 7 | ParamType::Float => { RustParam::Float(Qv::Null) } 8 | ParamType::String => { RustParam::String(Qv::Null) } 9 | ParamType::IntArray => { RustParam::IntArray(Qv::Null) } 10 | ParamType::FloatArray => { RustParam::FloatArray(Qv::Null) } 11 | ParamType::Binary => { RustParam::Binary(Qv::Null)} 12 | } 13 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/read/get_undefined.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{ParamType, RustParam, Qv}; 2 | 3 | pub(crate) fn get_undefined(pt : ParamType) -> RustParam{ 4 | match pt { 5 | ParamType::Bool => { RustParam::Bool(Qv::Undefined) } 6 | ParamType::Int => { RustParam::Int(Qv::Undefined) } 7 | ParamType::Float => { RustParam::Float(Qv::Undefined) } 8 | ParamType::String => { RustParam::String(Qv::Undefined) } 9 | ParamType::IntArray => { RustParam::IntArray(Qv::Undefined) } 10 | ParamType::FloatArray => { RustParam::FloatArray(Qv::Undefined) } 11 | ParamType::Binary =>{ RustParam::Binary(Qv::Undefined) } 12 | } 13 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/read/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod read_param; 2 | pub(crate) mod reader; 3 | pub(crate) mod get_null; 4 | pub(crate) mod get_undefined; 5 | pub(crate) mod read_root; 6 | pub(crate) mod read_lists; 7 | pub(crate) mod read_list; 8 | pub(crate) mod read_params; 9 | pub(crate) mod read_refs; 10 | pub(crate) mod read_store_ids; 11 | pub(crate) mod read_lists_numbers; -------------------------------------------------------------------------------- /docchi_diff/src/imp/read/read_lists_numbers.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::read::read_list::read_list; 2 | use docchi_core::structs::{MetaValue, MetaTable}; 3 | use crate::imp::read::reader::Reader; 4 | use crate::imp::structs_read::ListDiffR; 5 | use crate::diff_error::{DiffError, OptToErr}; 6 | 7 | pub(crate) fn read_lists_numbers(r: &mut Reader, meta: &MetaTable, n: &Vec, 8 | lists: &mut Vec<(usize, Option)>) -> Result<(), DiffError>{ 9 | for &id in n { 10 | if let Some((_, v)) = meta.get(id) { 11 | match v { 12 | MetaValue::OptMil(tables) => { 13 | if r.read()?.ast_bool()? { 14 | lists.push((id, Some(read_list(r, tables)?))); 15 | } else { 16 | lists.push((id, None)); 17 | } 18 | }, 19 | MetaValue::MList(tables) => { 20 | lists.push((id, Some(read_list(r, tables)?))); 21 | }, 22 | MetaValue::Param(_) => {} 23 | } 24 | } 25 | } 26 | Ok(()) 27 | } 28 | -------------------------------------------------------------------------------- /docchi_diff/src/imp/read/read_store_ids.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::read::reader::Reader; 2 | use crate::diff_error::{DiffError, OptToErr}; 3 | use crate::imp::write::store_ids::StoredIDs; 4 | 5 | pub(crate) fn read_stored_ids(r : &mut Reader) -> Result{ 6 | if r.read()?.ast_bool()?{ 7 | let bits = r.read()?.ast_i64()? as u64; 8 | if bits == 0{ 9 | return Ok(StoredIDs::Zero); 10 | } else{ 11 | return Ok(StoredIDs::U64(bits)); 12 | } 13 | } else{ 14 | if r.read()?.ast_bool()?{ 15 | let vec = r.read_u64_array()?; 16 | return Ok(StoredIDs::Bits(vec)) 17 | } else{ 18 | let vec = r.read_usize_array()?; 19 | return Ok(StoredIDs::Numbers(vec)); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /docchi_diff/src/imp/write/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod write_param; 2 | pub(crate) mod write_root; 3 | pub(crate) mod store_ids; 4 | pub(crate) mod write_list; 5 | pub(crate) mod write_refs; 6 | pub(crate) mod write_store_ids; -------------------------------------------------------------------------------- /docchi_diff/src/imp/write/write_store_ids.rs: -------------------------------------------------------------------------------- 1 | use docchi_compaction::kval_enum::KVal; 2 | use crate::imp::write::store_ids::StoredIDs; 3 | use docchi_compaction::basic_compaction::{comp_int}; 4 | 5 | pub(crate) fn write_stored_ids(s : &StoredIDs, r : &mut Vec){ 6 | match s { 7 | StoredIDs::Zero => { 8 | r.push(KVal::Bit(true)); 9 | r.push(KVal::Bit(false)); 10 | }, 11 | StoredIDs::U64(b) => { 12 | r.push(KVal::Bit(true)); 13 | r.push(comp_int(*b as i64)); 14 | }, 15 | StoredIDs::Bits(b) => { 16 | r.push(KVal::Bit(false)); 17 | r.push(KVal::Bit(true)); 18 | r.push(comp_int(b.len() as i64)); 19 | for &s in b { 20 | r.push(comp_int(s as i64)); 21 | } 22 | }, 23 | StoredIDs::Numbers(n) => { 24 | r.push(KVal::Bit(false)); 25 | r.push(KVal::Bit(false)); 26 | r.push(comp_int(n.len() as i64)); 27 | for &s in n { 28 | r.push(comp_int(s as i64)); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /docchi_diff/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny(unreachable_pub)] 2 | #![deny(unused_crate_dependencies)] 3 | 4 | mod imp; 5 | mod diff_error; 6 | 7 | pub use imp::get_diff::get_diff; 8 | pub use imp::get_diff::get_kvals; 9 | pub use imp::apply_diff::apply_diff; 10 | pub use imp::apply_diff::apply_root_diff_r; 11 | pub use imp::apply_diff::get_root_diff_r; 12 | pub use imp::structs_read::RootDiffR; 13 | pub use diff_error::{DiffResult, DiffError}; -------------------------------------------------------------------------------- /docchi_fs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_fs" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "A file system which composes chlonological diff files efficiently." 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["data","management","file","system", "diff"] 12 | 13 | [dependencies] 14 | docchi_core = {path="../docchi_core", version="0.8" } 15 | anyhow = "1.0.34" 16 | docchi_archiver2 = {path="../docchi_archiver2", version="0.8"} 17 | docchi_diff = {path="../docchi_diff", version="0.8"} 18 | docchi_compaction = {path="../docchi_compaction", version="0.8" } 19 | with_capacity_safe = "0.4" 20 | once_cell = "1.7.2" 21 | rayon = "1.5.1" 22 | threadpool = "1.8.1" -------------------------------------------------------------------------------- /docchi_fs/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_fs/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_fs/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/archive/get_archive_path.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | use crate::common::reserved_filename::ARCHIVE_DEFAULT_NAME; 3 | use crate::common::hash_dir_path; 4 | 5 | pub(crate) fn get_archive_path

>(dir_path : P) -> PathBuf{ 6 | dir_path.as_ref().join(ARCHIVE_DEFAULT_NAME) 7 | } 8 | 9 | pub(crate) fn get_archive_path2

>(history_dir : P, hash : u128) -> PathBuf{ 10 | get_archive_path(hash_dir_path(history_dir, hash)) 11 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/archive/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod get_archive_path; 2 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/current_src/current_src_info.rs: -------------------------------------------------------------------------------- 1 | use crate::common::CurrentSrc; 2 | use docchi_core::structs::RootObject; 3 | 4 | #[derive(Debug, Clone)] 5 | pub(crate) struct CurrentSrcInfo{ 6 | current_src : CurrentSrc, 7 | src_root : RootObject, 8 | hash : u128, 9 | } 10 | 11 | impl CurrentSrcInfo{ 12 | pub(crate) fn new(current_src : CurrentSrc, 13 | src_root : RootObject, 14 | hash : u128) -> CurrentSrcInfo{ 15 | CurrentSrcInfo{ current_src, src_root, hash, } 16 | } 17 | 18 | pub(crate) fn current_src(&self) -> &CurrentSrc{ &self.current_src } 19 | pub(crate) fn clone_src_root(&self) -> RootObject{ self.src_root.clone() } 20 | pub(crate) fn hash(&self) -> u128{ self.hash } 21 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/current_src/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod current_src; 2 | pub(crate) mod current_src_info; 3 | pub(crate) mod current_src_map; -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/list/find_next_dir.rs: -------------------------------------------------------------------------------- 1 | use std::fs::{ReadDir, read_dir}; 2 | use crate::error::FsResult; 3 | use crate::imp::common::path::hash::folder_name_to_hash; 4 | 5 | pub(crate) fn find_next_dir(dir_iter : &mut ReadDir) -> FsResult>{ 6 | loop { 7 | if let Some(entry) = dir_iter.next() { 8 | let entry = entry?; 9 | if entry.file_type()?.is_dir(){ 10 | //名前がhexであるdirectoryだけ探して返す 11 | if let Some(hex) = folder_name_to_hash(&entry.file_name()){ 12 | let d = read_dir(&entry.path())?; 13 | return Ok(Some((d, hex))); 14 | } 15 | } 16 | } else{ 17 | return Ok(None); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/list/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod list_files; 2 | pub(crate) mod file_data; 3 | pub(crate) mod list_files_iterator; 4 | pub(crate) mod find_next_dir; 5 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod current_src; 2 | pub(crate) mod path; 3 | pub(crate) mod archive; 4 | pub(crate) mod list; 5 | pub(crate) mod apply_items; 6 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/path/created_time_file.rs: -------------------------------------------------------------------------------- 1 | use std::io::{Write, Read}; 2 | use std::time::{SystemTime, Duration}; 3 | use crate::error::FsResult; 4 | 5 | 6 | pub(crate) fn create_time_dat(time : SystemTime, write : &mut W) -> FsResult<()>{ 7 | let std_time = time.duration_since(SystemTime::UNIX_EPOCH)?; 8 | let secs = std_time.as_secs(); 9 | let nanos = std_time.subsec_nanos(); 10 | write.write_all(&secs.to_le_bytes())?; 11 | write.write_all(&nanos.to_le_bytes())?; 12 | Ok(()) 13 | } 14 | 15 | pub(crate) fn from_time_dat(read : &mut R) -> FsResult{ 16 | let mut secs = [0 as u8;8]; 17 | read.read_exact(&mut secs)?; 18 | let mut nanos = [0 as u8; 4]; 19 | read.read_exact(&mut nanos)?; 20 | let secs = u64::from_le_bytes(secs); 21 | let nanos = u32::from_le_bytes(nanos); 22 | let time = SystemTime::UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_nanos(nanos as u64); 23 | Ok(time) 24 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/path/hash_dir_path.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | use crate::imp::common::path::hash::hash_to_folder_name; 3 | use crate::common::get_hash_times; 4 | use crate::error::FsResult; 5 | 6 | /// hash dir's path can be calculated with proj_dir(save_dir or history_dir)'s path and hash value 7 | pub fn hash_dir_path

>(proj_dir: P, hash : u128) -> PathBuf{ 8 | let name = hash_to_folder_name(hash); 9 | proj_dir.as_ref().join(&name) 10 | } 11 | 12 | /// Gets paths of hash directories 13 | pub fn hash_dir_paths

>(proj_dir: P) -> FsResult>{ 14 | let proj_dir = proj_dir.as_ref(); 15 | let hash_times = get_hash_times(proj_dir)?; 16 | let proj_dir = PathBuf::from(proj_dir); 17 | Ok(hash_times.into_iter().map(move |(hash, _time)| hash_dir_path(&proj_dir, hash))) 18 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/path/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod hash_dir_path; 2 | pub(crate) mod hash; 3 | pub(crate) mod created_time_file; 4 | pub(crate) mod get_hash_times; 5 | pub mod reserved_filename; 6 | pub(crate) mod prepare_hash_dir; 7 | pub(crate) mod remove_hash_dir; 8 | 9 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/path/remove_hash_dir.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use crate::imp::common::path::hash_dir_path::hash_dir_path; 4 | 5 | ///we can safely remove hash dirs. 6 | pub fn remove_hash_dir

>(proj_dir : P, hash : u128) -> FsResult<()>{ 7 | Ok(std::fs::remove_dir_all(hash_dir_path(proj_dir, hash))?) 8 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/common/path/reserved_filename.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | /// The default name of generated archive files 4 | pub const ARCHIVE_DEFAULT_NAME : &'static str = "src.archive"; 5 | 6 | /// the file name of the files which contains "created time" 7 | pub const CREATED_TIME_FILE_NAME : &'static str = "created_time.dat"; 8 | 9 | pub(crate) fn is_reserved_filename(filename : &str) -> bool{ 10 | filename == ARCHIVE_DEFAULT_NAME || filename == CREATED_TIME_FILE_NAME 11 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/filesys/docchi_mutex.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::filesys::save_cache_item::SaveCacheItem; 2 | use std::sync::atomic::Ordering; 3 | use std::sync::MutexGuard; 4 | 5 | pub(crate) struct DocchiMutex<'a>{ 6 | _guard: MutexGuard<'a, ()>, 7 | cache: &'a SaveCacheItem, 8 | } 9 | impl<'a> DocchiMutex<'a>{ 10 | pub(crate) fn new<'b>(guard : MutexGuard<'b, ()>, 11 | cache : &'b SaveCacheItem) -> DocchiMutex<'b>{ 12 | cache.queued_atomic().fetch_add(1, Ordering::Relaxed); 13 | DocchiMutex { _guard: guard, cache } 14 | } 15 | pub(crate) fn cache(&self) -> &SaveCacheItem{ self.cache } 16 | } 17 | impl<'a> Drop for DocchiMutex<'a>{ 18 | fn drop(&mut self) { 19 | self.cache().queued_atomic().fetch_sub(1, Ordering::Relaxed); 20 | } 21 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/filesys/list_docchi_files.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::imp::common::list::file_data::FileData; 3 | use crate::imp::common::list::list_files::list_files; 4 | use crate::error::FsResult; 5 | 6 | pub fn list_docchi_files

>(save_dir : P) -> FsResult>{ 7 | list_files(save_dir) 8 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/filesys/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod load_docchi_file; 2 | pub(crate) mod save_docchi_file; 3 | pub(crate) mod list_docchi_files; 4 | pub(crate) mod remove_docchi_file; 5 | pub(crate) mod save_cache_map; 6 | pub(crate) mod save_cache_item; 7 | pub(crate) mod save_dir_info; 8 | pub(crate) mod docchi_mutex; 9 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/filesys/remove_docchi_file.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use crate::imp::common::path::reserved_filename::is_reserved_filename; 4 | use crate::imp::common::path::hash_dir_path::hash_dir_path; 5 | 6 | ///Docchi files can be safely removed. 7 | pub fn remove_docchi_file

>(save_dir : P, hash : u128, filename : &str) -> FsResult<()>{ 8 | if is_reserved_filename(filename) == false{ 9 | let dir = hash_dir_path(save_dir, hash); 10 | let file_path = dir.join(filename); 11 | Ok(std::fs::remove_file(file_path)?) 12 | } else{ 13 | Err(format!("{} couldn't be removed. {} is a system file.", filename, filename))? 14 | } 15 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/filesys/save_cache_item.rs: -------------------------------------------------------------------------------- 1 | use crate::common::CurrentSrc; 2 | use std::path::{Path}; 3 | use docchi_core::structs::RootObject; 4 | use crate::imp::filesys::save_dir_info::SaveDirInfo; 5 | use std::sync::atomic::{AtomicUsize, Ordering}; 6 | 7 | #[derive(Debug)] 8 | pub(crate) struct SaveCacheItem{ 9 | info : SaveDirInfo, 10 | queued : AtomicUsize, 11 | } 12 | 13 | impl SaveCacheItem{ 14 | pub(crate) fn new(info : SaveDirInfo) -> SaveCacheItem{ 15 | SaveCacheItem{ info, queued : AtomicUsize::new(0) } 16 | } 17 | 18 | 19 | pub(crate) fn clone_dir_info(&self) -> SaveDirInfo{ self.info.clone() } 20 | pub(crate) fn save_dir(&self) -> &Path{ self.info.save_dir() } 21 | pub(crate) fn current_src(&self) -> &CurrentSrc{ self.info.current_src() } 22 | pub(crate) fn hash(&self) -> u128{ self.info.hash() } 23 | pub(crate) fn clone_src_root(&self) -> RootObject{ self.info.clone_src_root() } 24 | pub(crate) fn queued(&self) -> usize{ self.queued.load(Ordering::Relaxed) } 25 | pub(crate) fn queued_atomic(&self) -> &AtomicUsize{ &self.queued } 26 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/algo/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod should_shift_to_parent_phase; 2 | pub(crate) mod phase_data; 3 | pub(crate) mod phase_data_item; 4 | pub(crate) mod calc_next_phase; 5 | pub(crate) mod history_options; -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/algo/should_shift_to_parent_phase.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | ///上のphaseへの移行をすべきか 4 | pub(crate) fn should_shift_to_parent_phase( 5 | parent_size : u64, descendant_total_size : u64, descendant_total_len : usize, 6 | current_total_size: u64, current_total_len: usize) -> bool{ 7 | 8 | //平行phase shiftをした場合。currentが繰り返されるものと仮定。 9 | let size = parent_size + descendant_total_size + current_total_size; 10 | let len = 1 + descendant_total_len + current_total_len; 11 | let average_normal_shift = size as f64 / len as f64; 12 | 13 | //継続せず次のcumにshiftした場合 14 | let size = parent_size + descendant_total_size; 15 | let len = 1 + descendant_total_len; 16 | let average_parent_shift = size as f64 / len as f64; 17 | 18 | 19 | return average_normal_shift > average_parent_shift; 20 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/current_root_obj_info/current_root_obj_info.rs: -------------------------------------------------------------------------------- 1 | use crate::history::FileNameProps; 2 | use std::sync::Weak; 3 | 4 | #[derive(Debug, Clone)] 5 | pub struct CurrentRootObjInfo { 6 | current_root_id: Weak<()>, 7 | current_base_file: FileNameProps, 8 | } 9 | 10 | impl CurrentRootObjInfo { 11 | pub fn new(current_root_id: Weak<()>, current_base_file: FileNameProps) -> CurrentRootObjInfo { 12 | CurrentRootObjInfo { current_root_id, current_base_file} 13 | } 14 | 15 | pub fn current_root_id(&self) -> &Weak<()>{ &self.current_root_id } 16 | pub fn current_base_file(&self) -> &FileNameProps{ &self.current_base_file } 17 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/current_root_obj_info/fifo_thread.rs: -------------------------------------------------------------------------------- 1 | use threadpool::ThreadPool; 2 | use std::sync::Mutex; 3 | 4 | pub(crate) struct FifoThread{ 5 | pool : Mutex>, 6 | } 7 | 8 | impl FifoThread{ 9 | pub(crate) fn new() -> FifoThread{ 10 | FifoThread{ pool : Mutex::new(None) } 11 | } 12 | 13 | pub(crate) fn spawn_fifo(&self, f : F){ 14 | let mut opt = self.pool.lock().unwrap(); 15 | if opt.is_none(){ 16 | *opt = Some(ThreadPool::new(1)) 17 | } 18 | if let Some(p) = opt.as_ref(){ 19 | p.execute(f); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/current_root_obj_info/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod current_root_obj_info; 2 | pub(crate) mod history_cache_map; 3 | pub(crate) mod history_cache_item; 4 | pub(crate) mod mutex_g; 5 | pub(crate) mod fifo_thread; 6 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/accumulate_diff.rs: -------------------------------------------------------------------------------- 1 | // use crate::error::FsResult; 2 | // use std::path::{ PathBuf}; 3 | // use crate::imp::history::diff_and_cache::diff_src::DiffSrc; 4 | // use crate::imp::history::diff_and_cache::diff_value::DiffValue; 5 | // use crate::imp::history::diff_and_cache::open_diff_file_without_metadata::open_diff_file_without_metadata; 6 | // 7 | 8 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/cache.rs: -------------------------------------------------------------------------------- 1 | use std::path::{PathBuf}; 2 | use crate::error::FsResult; 3 | use crate::imp::history::diff_and_cache::diff_src::DiffSrc; 4 | use crate::imp::history::diff_and_cache::diff_value::DiffValue; 5 | use crate::history::HistoryOptions; 6 | 7 | pub(crate) trait Cache>{ 8 | 9 | 10 | fn apply_items_for_save(&mut self, paths : Vec, op : &HistoryOptions) -> FsResult; 11 | fn apply_items_for_load(&mut self, load_root : S, paths : Vec, op : &HistoryOptions) -> FsResult; 12 | fn set_cache(&mut self, path : PathBuf, item : S, phase : usize) -> FsResult<()>; 13 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/diff_src.rs: -------------------------------------------------------------------------------- 1 | use crate::error::FsResult; 2 | use crate::imp::history::diff_and_cache::diff_value::{DiffValue}; 3 | 4 | pub(crate) trait DiffSrc : Clone{ 5 | fn create_diff(&self, from: &Self) -> FsResult; 6 | fn apply_diff(&mut self, diff : V) -> FsResult<()>; 7 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/diff_value.rs: -------------------------------------------------------------------------------- 1 | use crate::error::FsResult; 2 | use std::io::{Read, Write}; 3 | 4 | pub(crate) trait DiffValue : Sized{ 5 | fn read_value(read : &mut R) -> FsResult; 6 | fn write_value(&self, write : &mut W) -> FsResult<()>; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/docchi_src.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::history::diff_and_cache::diff_src::DiffSrc; 2 | use docchi_core::structs::{RootObject}; 3 | use crate::error::FsResult; 4 | use crate::imp::history::diff_and_cache::docchi_diff::DocchiDiff; 5 | 6 | 7 | impl DiffSrc for RootObject{ 8 | 9 | fn create_diff(&self, from: &Self) -> FsResult { 10 | let vec = docchi_diff::get_diff(&from, self)?; 11 | Ok(DocchiDiff::new(vec)) 12 | } 13 | 14 | fn apply_diff(&mut self, diff: DocchiDiff) -> FsResult<()> { 15 | docchi_diff::apply_diff(self, &mut diff.slice())?; 16 | Ok(()) 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/impl_cache_for_docchi_cache.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::history::diff_and_cache::cache::Cache; 2 | use std::path::{PathBuf}; 3 | use crate::error::FsResult; 4 | use docchi_core::structs::RootObject; 5 | use crate::imp::history::diff_and_cache::docchi_diff::DocchiDiff; 6 | use crate::history::HistoryOptions; 7 | use crate::imp::history::diff_and_cache::docchi_cache::DocchiCache; 8 | 9 | 10 | impl Cache for DocchiCache { 11 | 12 | 13 | fn apply_items_for_save(&mut self, paths: Vec, op: &HistoryOptions) -> FsResult { 14 | self.apply_items_for_save(paths, op) 15 | } 16 | 17 | fn apply_items_for_load(&mut self, load_root: RootObject, paths: Vec, op: &HistoryOptions) -> FsResult { 18 | self.apply_items_for_load(load_root, paths, op) 19 | } 20 | 21 | fn set_cache(&mut self, path : PathBuf, item: RootObject, phase: usize) -> FsResult<()> { 22 | self.set_cache(path, item, phase); 23 | Ok(()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod cache; 2 | pub(crate) mod diff_src; 3 | pub(crate) mod accumulate_diff; 4 | pub(crate) mod diff_value; 5 | pub(crate) mod docchi_src; 6 | pub(crate) mod docchi_diff; 7 | pub(crate) mod impl_cache_for_docchi_cache; 8 | pub(crate) mod open_diff_file_without_metadata; 9 | pub(crate) mod docchi_cache; 10 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/diff_and_cache/open_diff_file_without_metadata.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use std::fs::File; 4 | 5 | /// 最初のメタデータを省いて返す 6 | pub(crate) fn open_diff_file_without_metadata(path : &Path) -> FsResult{ 7 | let mut file = File::open(&path)?; 8 | 9 | let (_first, _) = docchi_compaction::enc_dec::decode::decode(&mut file)?; 10 | 11 | Ok(file) 12 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/file_hist/create_file_history.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path}; 2 | use crate::error::FsResult; 3 | use crate::imp::history::file_hist::file_history::FileHistory; 4 | use crate::imp::history::file_name::analyze_file_name::analyze_file_name; 5 | 6 | 7 | pub(crate) fn create_file_history(history_hash_dir: &Path, max_phase : usize, cumulative : bool) -> FsResult{ 8 | let dir = std::fs::read_dir(history_hash_dir)?; 9 | let mut history = FileHistory::new(max_phase, cumulative); 10 | for entry in dir { 11 | let entry = entry?; 12 | let filename = entry.path().file_name() 13 | .ok_or_else(|| format!("The filename couldn't be found {:?}", entry.path()))?.to_string_lossy().to_string(); 14 | if let Some(props) = analyze_file_name(&filename, Some(max_phase)) { 15 | history.add(props) 16 | } else{ 17 | } 18 | } 19 | Ok(history) 20 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/file_hist/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod file_history; 2 | pub(crate) mod create_file_history; 3 | pub(crate) mod file_history_item; 4 | pub(crate) mod ancestors; 5 | pub(crate) mod history_file_data; 6 | pub(crate) mod file_histories; 7 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/file_name/calc_filename.rs: -------------------------------------------------------------------------------- 1 | /// History's filenames have a tag(arbitrary string given by user) 2 | /// control number(increases when start_new is called) 3 | /// order( numbers ancestors of this history file have. 4 | /// if order is (1,2,1,1) ancestors have orders 5 | /// (1)<- grand grandparent 6 | /// (1,2)<- grand parent 7 | /// (1,2,1)<- parent ) 8 | pub fn calc_filename(tag : Option<&str>, control : u32, prev_ctl : Option, order: &[u32]) -> String{ 9 | let mut s = String::new(); 10 | 11 | if let Some(tag) = tag{ 12 | s.push('#'); 13 | s.push_str(&tag); 14 | s.push('#'); 15 | } 16 | if let Some(prev_ctl) = prev_ctl{ 17 | s.push('('); 18 | s.push_str(&prev_ctl.to_string()); 19 | s.push(')'); 20 | } 21 | s.push('_'); 22 | s.push_str(&control.to_string()); 23 | for phase in order { 24 | s.push('_'); 25 | s.push_str(&*phase.to_string()) 26 | } 27 | s.push_str(".his"); 28 | s 29 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/file_name/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod file_name_props; 2 | pub(crate) mod analyze_file_name; 3 | pub(crate) mod calc_filename; 4 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/fs/derive.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use crate::imp::history::diff_and_cache::diff_src::DiffSrc; 4 | use crate::imp::history::diff_and_cache::diff_value::DiffValue; 5 | use crate::imp::history::diff_and_cache::cache::Cache; 6 | use crate::imp::history::algo::history_options::{HistoryOptions}; 7 | use crate::imp::history::file_hist::create_file_history::create_file_history; 8 | use crate::history::FileNameProps; 9 | use crate::imp::history::fs::derive_impl::derive_impl; 10 | 11 | 12 | pub(crate) fn _derive< 13 | V : DiffValue, 14 | S: DiffSrc, 15 | C : Cache, 16 | P : AsRef, 17 | Op : AsRef>(tag : Option, 18 | diff_src: &S, 19 | cache : &mut C, 20 | history_hash_dir: P, 21 | from : &FileNameProps, 22 | opt: Op) -> FsResult { 23 | let history_hash_dir = history_hash_dir.as_ref(); 24 | let opt = opt.as_ref(); 25 | let history = create_file_history(history_hash_dir, opt.max_phase(), opt.is_cumulative())?; 26 | 27 | derive_impl(tag, diff_src, cache, history_hash_dir, &history, from, opt) 28 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/fs/first.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use crate::imp::history::fs::write_phase_0::write_phase_0; 4 | use crate::imp::history::diff_and_cache::diff_src::DiffSrc; 5 | use crate::imp::history::diff_and_cache::diff_value::DiffValue; 6 | use crate::imp::history::diff_and_cache::cache::Cache; 7 | use crate::imp::history::file_name::file_name_props::FileNameProps; 8 | use crate::history::HistoryOptions; 9 | 10 | pub(crate) fn first, C : Cache>( 11 | tag : Option, diff_src : &S, cache : &mut C, op : &HistoryOptions, history_hash_dir: &Path) 12 | -> FsResult{ 13 | write_phase_0(tag, 0, diff_src, cache, op, history_hash_dir) 14 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/fs/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod next; 2 | pub(crate) mod start_new; 3 | pub(crate) mod first; 4 | pub(crate) mod write_phase_0; 5 | pub(crate) mod write_phase_file; 6 | pub(crate) mod load; 7 | pub(crate) mod derive; 8 | pub(crate) mod derive_impl; 9 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/fs/write_phase_file.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::error::FsResult; 3 | use crate::imp::history::algo::phase_data::PhaseData; 4 | use std::io::Write; 5 | 6 | pub(crate) fn write_phase_file(data : &PhaseData, file_path : &Path, vec : &[u8]) -> FsResult<()>{ 7 | let data_encoded = data.encode(); 8 | let mut file = std::fs::File::create(file_path)?; 9 | docchi_compaction::enc_dec::encode::encode(&data_encoded, &mut file)?; 10 | //let mut vec = vec; 11 | file.write_all(vec)?; 12 | Ok(()) 13 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod algo; 2 | pub(crate) mod fs; 3 | pub(crate) mod file_name; 4 | pub(crate) mod file_hist; 5 | pub(crate) mod diff_and_cache; 6 | pub(crate) mod pub_fn; 7 | pub(crate) mod remove; 8 | pub(crate) mod current_root_obj_info; 9 | pub(crate) mod history_info; 10 | -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/pub_fn/list_histories.rs: -------------------------------------------------------------------------------- 1 | 2 | use crate::history::{FileHistory, HistoryInfo}; 3 | use crate::common::get_hash_times; 4 | use crate::error::FsResult; 5 | use crate::imp::history::file_hist::file_histories::FileHistories; 6 | 7 | 8 | pub fn list_histories(info : &HistoryInfo) -> FsResult{ 9 | let history_dir = info.history_dir(); 10 | let hash_times = get_hash_times(history_dir)?; 11 | let opt = info.options(); 12 | 13 | let mut vec : Vec<(u128, FileHistory)> = vec![]; 14 | for (hash, _time) in hash_times{ 15 | if let Ok(history) = FileHistory::create(history_dir, hash, opt.max_phase(), opt.is_cumulative()){ 16 | vec.push((hash, history)); 17 | } 18 | } 19 | 20 | Ok(FileHistories::new(vec)) 21 | } -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/pub_fn/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod list_histories; 2 | pub(crate) mod load_history_file; 3 | pub(crate) mod save_history_file; -------------------------------------------------------------------------------- /docchi_fs/src/imp/history/remove/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod history_remover; 2 | pub(crate) mod history_remover_item; 3 | pub(crate) mod composite_remover; 4 | pub(crate) mod btree_zipper; -------------------------------------------------------------------------------- /docchi_fs/src/imp/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | pub(crate) mod filesys; 3 | 4 | pub(crate) mod history; 5 | pub(crate) mod common; 6 | -------------------------------------------------------------------------------- /docchi_fs/src/json_dir/simple/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | b : false, 3 | int : 10, 4 | float : 12.0, 5 | s : "sutoringu", 6 | } -------------------------------------------------------------------------------- /docchi_fs/src/json_dir/simple_mod1/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | b : false, 3 | int : 10, 4 | float : 12.0, 5 | s : "sutoringu", 6 | added : 100, 7 | } -------------------------------------------------------------------------------- /docchi_fs/src/json_dir/simple_mod2/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | b : false, 3 | int : 10, 4 | float : 12.0, 5 | s : "sutoringu", 6 | added : 101, 7 | } -------------------------------------------------------------------------------- /docchi_fs/src/json_dir/simple_mod3/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | b : false, 3 | int : 10, 4 | float : 12.0, 5 | s : "sutoringu", 6 | added : 103, 7 | } -------------------------------------------------------------------------------- /docchi_fs/src/json_dir/simple_mod4/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | b : false, 3 | int : 10, 4 | float : 12.0, 5 | s : "sutoringu", 6 | added : 104, 7 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_diff_history/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_diff_his; 2 | mod show_dir_contents_diff_history; -------------------------------------------------------------------------------- /docchi_fs/src/test_diff_history/show_dir_contents_diff_history.rs: -------------------------------------------------------------------------------- 1 | use crate::error::FsResult; 2 | use std::fs::{File}; 3 | use crate::history::{list_histories, HistoryInfo}; 4 | 5 | pub fn show_dir_contents_diff_history(info : &HistoryInfo) -> FsResult>{ 6 | let proj_dir = info.history_dir(); 7 | let histories = list_histories(info)?; 8 | let mut r : Vec<(u128, String, u64)> = vec![]; 9 | for item in histories.list_files(){ 10 | let name = item.props().calc_filename(); 11 | let file = File::open(item.calc_path(proj_dir))?; 12 | r.push((item.hash(), name, file.metadata()?.len())) 13 | } 14 | Ok(r) 15 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_fs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod test_hex_file_name; 2 | pub mod save_test; 3 | pub mod show_dir_contents_fs; 4 | pub mod copy_dir_all; 5 | mod test_fifo_thread; -------------------------------------------------------------------------------- /docchi_fs/src/test_fs/show_dir_contents_fs.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | use crate::error::FsResult; 3 | use std::fs::{read_dir}; 4 | 5 | pub fn show_dir_contents_fs

>(path : P) -> FsResult>{ 6 | let mut r : Vec = vec![]; 7 | collect_dir_contents(path.as_ref(), &mut r)?; 8 | Ok(r) 9 | } 10 | 11 | fn collect_dir_contents(path : &Path, r : &mut Vec) -> FsResult<()>{ 12 | let dir = read_dir(path)?; 13 | 14 | let mut dirs : Vec = vec![]; 15 | 16 | for item in dir{ 17 | let entry = item?; 18 | r.push(entry.path()); 19 | if entry.file_type()?.is_dir(){ 20 | dirs.push(entry.path()); 21 | } 22 | } 23 | 24 | for dir_path in dirs{ 25 | collect_dir_contents(&dir_path, r)?; 26 | } 27 | Ok(()) 28 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_fs/test_fifo_thread.rs: -------------------------------------------------------------------------------- 1 | use crate::FsResult; 2 | use crate::imp::history::current_root_obj_info::fifo_thread::FifoThread; 3 | use std::thread::sleep; 4 | use std::time::Duration; 5 | 6 | //#[test] 7 | fn test_fifo_thread() -> FsResult<()>{ 8 | let th = FifoThread::new(); 9 | for i in 0..100 { 10 | th.spawn_fifo(move ||{ 11 | println!("{}",i); 12 | sleep(Duration::from_millis(100)); 13 | }); 14 | } 15 | sleep(Duration::from_millis(10000)); 16 | Ok(()) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /docchi_fs/src/test_fs/test_hex_file_name.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::common::path::hash::{hash_to_folder_name, folder_name_to_hash}; 2 | 3 | #[test] 4 | fn test_hex_file_name() { 5 | let val: u128 = 123456789123456789123456789; 6 | let file_name = hash_to_folder_name(val); 7 | match folder_name_to_hash(&file_name) { 8 | Some(hex) => { 9 | assert_eq!(val, hex); 10 | } 11 | None =>{ 12 | assert!(false) 13 | }, 14 | } 15 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/history2/create_file_history2.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path}; 2 | use crate::error::FsResult; 3 | use crate::imp::history::file_name::analyze_file_name::analyze_file_name; 4 | use crate::test_simple_history::history2::file_history2::FileHistory2; 5 | use docchi_compaction::enc_dec::decode::decode; 6 | 7 | 8 | pub(crate) fn create_file_history2(dir_path : &Path, hint_max_phase : Option) -> FsResult{ 9 | let dir = std::fs::read_dir(dir_path)?; 10 | let mut history = FileHistory2::new(); 11 | for entry in dir { 12 | let entry = entry?; 13 | let filename = entry.path().file_name()?.to_string_lossy().to_string(); 14 | let len = entry.metadata()?.len(); 15 | 16 | if let Some(props) = analyze_file_name(&filename, hint_max_phase) { 17 | let mut file = std::fs::File::open(entry.path())?; 18 | let (_,tag_size) = decode(&mut file)?; 19 | let size = len - tag_size as u64; 20 | history.add(props, size) 21 | } 22 | } 23 | Ok(history) 24 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/history2/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod create_file_history2; 2 | pub mod file_history2; 3 | pub mod file_history_item2; -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod simple_diff; 2 | pub mod show_dir_contents_history; 3 | mod test_simple_diff_files; 4 | mod test_cumulative_limit_nth; 5 | pub mod history2; 6 | mod test_cumulative_limit_count; 7 | 8 | mod test_max_phase0; 9 | mod test_max_phase0_with_cumu; 10 | mod test_load_and_save; 11 | -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/show_dir_contents_history.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path}; 2 | use crate::error::FsResult; 3 | use std::fs::{read_dir}; 4 | use std::time::SystemTime; 5 | 6 | pub(crate) fn show_dir_contents_history

>(path : P) -> FsResult>{ 7 | let mut r : Vec<(SystemTime, String,usize)> = vec![]; 8 | let dir = read_dir(path)?; 9 | 10 | for item in dir{ 11 | let entry = item?; 12 | 13 | let name = entry.path().file_name()?.to_string_lossy().to_string(); 14 | let size = entry.metadata()?.len() as usize; 15 | let time = entry.metadata()?.created()?; 16 | r.push((time, name,size)); 17 | } 18 | r.sort_by_key(|a| a.0); 19 | let r : Vec<(String, usize)> = r.into_iter().map(|(_,s,u)| (s,u)).collect(); 20 | Ok(r) 21 | } 22 | 23 | pub fn show_history_dir

>(path : P) -> FsResult<()>{ 24 | let hoge = show_dir_contents_history(path)?; 25 | for (name,size) in &hoge{ 26 | println!("{} {}", name, size); 27 | } 28 | Ok(()) 29 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/simple_diff/create_sd_diff.rs: -------------------------------------------------------------------------------- 1 | use crate::test_simple_history::simple_diff::sd_data::SdData; 2 | use crate::test_simple_history::simple_diff::sd_diff::{SdDiff, SdDiffItem}; 3 | 4 | pub(crate) fn create_sd_diff(from : &SdData, to : &SdData) -> SdDiff{ 5 | let mut vec : Vec = vec![]; 6 | for i in 0..from.len(){ 7 | let f = from.get(i).unwrap(); 8 | if let Some(t) = to.get(i){ 9 | if f != t{ 10 | vec.push(SdDiffItem::new(i, t)) 11 | } 12 | } 13 | } 14 | SdDiff::new(vec) 15 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/simple_diff/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod sd_data; 2 | pub mod sd_diff; 3 | pub mod create_sd_diff; 4 | pub mod sd_data_diff_src; 5 | pub mod sd_diff_diff_value; 6 | pub mod sd_cache; -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/simple_diff/sd_data_diff_src.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::history::diff_and_cache::diff_src::{DiffSrc}; 2 | use crate::test_simple_history::simple_diff::sd_data::SdData; 3 | use crate::error::FsResult; 4 | use crate::test_simple_history::simple_diff::sd_diff::SdDiff; 5 | use crate::test_simple_history::simple_diff::create_sd_diff::create_sd_diff; 6 | 7 | impl DiffSrc for SdData{ 8 | 9 | 10 | 11 | fn create_diff(&self, from: &Self) -> FsResult { 12 | Ok(create_sd_diff(from, self)) 13 | } 14 | 15 | fn apply_diff(&mut self, diff: SdDiff) -> FsResult<()> { 16 | SdData::apply_diff(self, &diff) 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /docchi_fs/src/test_simple_history/simple_diff/sd_diff_diff_value.rs: -------------------------------------------------------------------------------- 1 | use crate::imp::history::diff_and_cache::diff_value::{DiffValue}; 2 | use crate::error::FsResult; 3 | use crate::test_simple_history::simple_diff::sd_diff::SdDiff; 4 | use std::io::{Read, Write}; 5 | use docchi_compaction::enc_dec::decode::decode; 6 | 7 | impl DiffValue for SdDiff{ 8 | fn read_value(read: &mut R) -> FsResult { 9 | let (kvals, _) = decode(read)?; 10 | SdDiff::decode_kvals(&kvals) 11 | } 12 | 13 | fn write_value(&self, write: &mut W) -> FsResult<()> { 14 | self.encode(write) 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /docchi_intf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_intf" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "Generates the source code to access Docchi Data" 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["data", "management"] 12 | 13 | [dependencies] 14 | docchi_core = {path="../docchi_core", version="0.8"} 15 | anyhow = "1.0.34" 16 | -------------------------------------------------------------------------------- /docchi_intf/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_intf/license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docchi_intf/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) -------------------------------------------------------------------------------- /docchi_intf/src/imp/generate_accessor_from_json_dir.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use crate::{IntfResult, generate_interface}; 3 | use docchi_core::json_dir_to_root; 4 | 5 | pub fn generate_accessor_from_json_dir

>(json_dir : P, output : P, validation : bool) -> IntfResult<()> { 6 | let r = json_dir_to_root(json_dir.as_ref(), validation)?; 7 | let ans = generate_interface(&r); 8 | std::fs::write( 9 | output.as_ref(), 10 | &ans.to_string() 11 | )?; 12 | Ok(()) 13 | } -------------------------------------------------------------------------------- /docchi_intf/src/imp/generate_interface.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::intf::*; 2 | use docchi_core::structs::RootObject; 3 | use crate::imp::structs::root_source::RootSource; 4 | use crate::imp::generate_root_source::generate_root_source; 5 | 6 | 7 | // データに静的にアクセスできるラッパーを生成する。 8 | // RootIntf::newしそこを起点にしてアクセスする。 9 | // RootIntfから取れたポインタは、RootIntfが削除されれば全て不正になる 10 | 11 | /// Generates Rust source code to access the root object 12 | pub fn generate_interface(root : &RootObject) -> RootSource{ 13 | let mem_descs = member_desc::get_member_desc(root); 14 | generate_root_source(&mem_descs) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /docchi_intf/src/imp/generate_root_source.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::intf::member_desc::MemberDesc; 2 | use crate::imp::structs::root_source::RootSource; 3 | use crate::imp::to_member_source::{to_member_source, MemberSource}; 4 | 5 | pub(crate) fn generate_root_source(mems : &[MemberDesc]) -> RootSource{ 6 | let mut members : Vec = vec![]; 7 | for mem in mems{ 8 | members.push(to_member_source(mem)) 9 | } 10 | RootSource::new(members) 11 | } -------------------------------------------------------------------------------- /docchi_intf/src/imp/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generate_root_source; 2 | pub mod to_member_source; 3 | pub mod generate_interface; 4 | pub mod structs; 5 | pub mod util; 6 | pub mod generate_accessor_from_json_dir; 7 | -------------------------------------------------------------------------------- /docchi_intf/src/imp/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod mil_source; 2 | pub mod mitem_source; 3 | pub mod mlist_source; 4 | pub mod cil_source; 5 | pub mod clist_source; 6 | pub mod ref_source; 7 | pub mod citem_source; 8 | pub mod table_source; 9 | pub mod param_source; 10 | pub mod root_source; 11 | pub mod source_builder; 12 | pub mod refs_source; 13 | -------------------------------------------------------------------------------- /docchi_intf/src/imp/structs/source_builder.rs: -------------------------------------------------------------------------------- 1 | 2 | pub(crate) struct SourceBuilder{ 3 | pub(crate) s : String, 4 | } 5 | impl SourceBuilder{ 6 | pub(crate) fn new() -> SourceBuilder{ SourceBuilder{ s : String::new() }} 7 | pub(crate) fn push(&mut self, tabs : usize, s : &str){ 8 | for line in s.split('\n'){ 9 | self.s.push_str(&tab_line(tabs, line)); 10 | } 11 | } 12 | pub(crate) fn push_without_newline(&mut self, tabs : usize, s : &str) { 13 | let s = 14 | if s.ends_with('\n'){ 15 | &s[0..(s.len()-1)] 16 | } else{ 17 | s 18 | }; 19 | for line in s.split('\n') { 20 | self.s.push_str(&tab_line(tabs, line)); 21 | } 22 | 23 | } 24 | 25 | pub(crate) fn append(&mut self, s : &str) { 26 | self.s.push_str(s); 27 | } 28 | 29 | pub(crate) fn to_string(&self) -> String{ 30 | self.s.to_string() 31 | } 32 | } 33 | 34 | 35 | fn tab_line(tabs : usize, s : &str) -> String{ 36 | let mut r : String = String::new(); 37 | for _ in 0..tabs{ 38 | r.push('\t'); 39 | } 40 | r.push_str(s); 41 | r.push('\n'); 42 | r 43 | } -------------------------------------------------------------------------------- /docchi_intf/src/imp/util/into_qv.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::VarType; 2 | 3 | pub(crate) fn into_qv(name : &str, var_type : VarType) -> String{ 4 | if var_type == VarType::Normal { 5 | format!("Qv::Val({})", name) 6 | } else { 7 | format!("{}.into_qv()", name) 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /docchi_intf/src/imp/util/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod with_var; 2 | pub mod with_old; 3 | pub mod to_type_name; 4 | pub mod into_qv; -------------------------------------------------------------------------------- /docchi_intf/src/imp/util/with_old.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn with_old(name : &str, is_old : bool) -> String { 2 | if is_old { 3 | format!("{}_old", name) 4 | } else { 5 | name.to_string() 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docchi_intf/src/imp/util/with_var.rs: -------------------------------------------------------------------------------- 1 | use docchi_core::structs::{VarType}; 2 | 3 | pub(crate) fn with_var(t : &str, vt : VarType) -> String{ 4 | match vt{ 5 | VarType::Normal => t.to_string(), 6 | VarType::Nullable => format!("NullOr<{}>", t), 7 | VarType::Undefiable => format!("UndefOr<{}>", t), 8 | VarType::UndefNullable => format!("Qv<{}>", t), 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /docchi_intf/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | mod imp; 3 | mod error; 4 | 5 | pub use imp::generate_interface::generate_interface; 6 | pub use imp::generate_accessor_from_json_dir::generate_accessor_from_json_dir; 7 | pub use imp::structs::root_source::RootSource; 8 | pub use error::{IntfError, IntfResult}; -------------------------------------------------------------------------------- /docchi_json5/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_json5" 3 | version = "0.8.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | description = "Handles customized json5 for my project" 9 | repository = "https://github.com/dochy-ksti/docchi" 10 | readme = "readme.md" 11 | keywords = ["json5"] 12 | 13 | [dependencies] 14 | pest = "2.0" 15 | pest_derive = "2.0" 16 | linked-hash-map = "0.5.2" 17 | fnv = "1.0.7" 18 | anyhow = "1.0.34" 19 | -------------------------------------------------------------------------------- /docchi_json5/apache_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Licensed under the Apache License, Version 2.0 (the “License”); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an “AS IS” BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docchi_json5/json5_rs_licence.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright 2018 Callum Oakley 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /docchi_json5/licence.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | © 2021 GitHub, Inc. -------------------------------------------------------------------------------- /docchi_json5/readme.md: -------------------------------------------------------------------------------- 1 | One of the components of [Docchi](https://github.com/dochy-ksti/docchi) 2 | 3 | This is directly derived from [json5-rs](https://github.com/callum-oakley/json5-rs). -------------------------------------------------------------------------------- /docchi_json5/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod de; 2 | pub mod error; 3 | 4 | pub mod deserialize_item; 5 | mod test; 6 | pub mod jval; 7 | 8 | pub use crate::de::from_str; 9 | pub use crate::jval::{JVal, Span}; 10 | pub use crate::error::MyError; -------------------------------------------------------------------------------- /docchi_json5/src/test.rs: -------------------------------------------------------------------------------- 1 | 2 | #[cfg(test)] 3 | mod tests { 4 | 5 | 6 | #[test] 7 | fn it_works() { 8 | let s = r#"{ a : 100, b : "abc" }"#.to_string(); 9 | 10 | crate::de::from_str(&s).unwrap(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docchi_manual/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_manual" 3 | version = "0.6.1" 4 | authors = ["Juzy "] 5 | edition = "2018" 6 | 7 | license= "MIT OR Apache-2.0" 8 | 9 | [dependencies] 10 | docchi = { path="../../docchi" } 11 | docchi_core = { path="../docchi_core" } 12 | # docchi_diff ={ path="../docchi_diff" } 13 | anyhow = "1.0" -------------------------------------------------------------------------------- /docchi_manual/manual/a4_clist_use_cil.rs.md: -------------------------------------------------------------------------------- 1 | [prev](a4_clist_cil_root.json5.md) 2 | [index](index.md) 3 | [next](a5_mlist_mlist_root.json5.md) 4 | 5 | ### 2-2. Use Clist And Cil 6 | 7 | ```rust 8 | use anyhow::Result; 9 | use docchi::core::structs::RootObject; 10 | use docchi::core::json_dir_to_root; 11 | use crate::a4_clist::cil_accessor::RootIntf; 12 | 13 | //#[test] 14 | fn cil_test() -> Result<()> { 15 | let root_obj : RootObject = json_dir_to_root("src/a4_clist/cil", false)?; 16 | 17 | let root = RootIntf::new(root_obj); 18 | 19 | // Iterates the CList 20 | for item in root.clist().iter(){ 21 | 22 | // Gets the inner list from the item. 23 | let il = item.inner_list(); 24 | println!("len {}", il.len()); 25 | // When inner_list is omitted in the source, len == 0 26 | 27 | // Iterates the inner list. 28 | for item in il.iter(){ 29 | println!("item name is {}", item.name()); 30 | } 31 | } 32 | // Output: 33 | // len 2 34 | // item name is p 35 | // item name is q 36 | // len 0 37 | Ok(()) 38 | } 39 | ``` 40 | 41 | 42 | [prev](a4_clist_cil_root.json5.md) 43 | [index](index.md) 44 | [next](a5_mlist_mlist_root.json5.md) 45 | -------------------------------------------------------------------------------- /docchi_manual/manual/a5_mlist_mlist_root.json5.md: -------------------------------------------------------------------------------- 1 | [prev](a4_clist_use_cil.rs.md) 2 | [index](index.md) 3 | [next](a5_mlist_mil_root.json5.md) 4 | 5 | ### 3. MList 6 | 7 | ```json5 8 | { 9 | // MList is a mutable list in Docchi. 10 | // Explanations are reserved for the next section. 11 | 12 | mlist : ["MList",[{ 13 | name : "a", 14 | val : 3, 15 | }], 16 | { 17 | name : "b", 18 | val : 4, 19 | }, 20 | { 21 | //name is omitted 22 | val : 5, 23 | } 24 | ], 25 | } 26 | ``` 27 | 28 | 29 | [prev](a4_clist_use_cil.rs.md) 30 | [index](index.md) 31 | [next](a5_mlist_mil_root.json5.md) 32 | -------------------------------------------------------------------------------- /docchi_manual/manual/b1_save_docchi_files_save_docchi_files.md.md: -------------------------------------------------------------------------------- 1 | [prev](a7_split_docchi_src_split_src.md.md) 2 | [index](index.md) 3 | [next](b1_save_docchi_files_save_docchi_file_test.rs.md) 4 | 5 | ### 6. Docchi File 6 | 7 | Let's save data in Docchi. 8 | 9 | There's two types of save files in Docchi, 10 | "Docchi File" and "Docchi History". 11 | 12 | Docchi File saves the difference from "Docchi Src". 13 | 14 | Simply put, Docchi History saves the difference from the previous save file. 15 | 16 | We'll talk about Docchi History later. Now let's move on. 17 | ```root.json5 18 | { 19 | message : "Hello World" 20 | } 21 | ``` 22 | This is the Docchi Src for this section. 23 | 24 | 25 | 26 | [prev](a7_split_docchi_src_split_src.md.md) 27 | [index](index.md) 28 | [next](b1_save_docchi_files_save_docchi_file_test.rs.md) 29 | -------------------------------------------------------------------------------- /docchi_manual/src/a1_hello_world/hello_world_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | 6 | #[test] 7 | fn hello_world_generate() -> Result<()> { 8 | let mut root_obj : RootObject = json_dir_to_root("src/a1_hello_world/src_dir", true)?; 9 | 10 | let ans = generate_interface(&mut root_obj); 11 | std::fs::write( 12 | "src/a1_hello_world/hello_world_accessor.rs", 13 | &ans.to_string(), 14 | ).unwrap(); 15 | Ok(()) 16 | } -------------------------------------------------------------------------------- /docchi_manual/src/a1_hello_world/mod.rs: -------------------------------------------------------------------------------- 1 | mod hello_world_accessor; 2 | mod hello_world_generate; 3 | mod hello_world_save_test; 4 | -------------------------------------------------------------------------------- /docchi_manual/src/a1_hello_world/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | message : "Hello World" 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/a3_docchi_langs_basics/mod.rs: -------------------------------------------------------------------------------- 1 | mod docchi_params_generate; 2 | mod docchi_params_accessor; 3 | mod params_test; 4 | -------------------------------------------------------------------------------- /docchi_manual/src/a4_clist/cil_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::{generate_accessor_from_json_dir}; 3 | 4 | #[test] 5 | fn cil_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/a4_clist/cil", "src/a4_clist/cil_accessor.rs", true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/a4_clist/clist_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn clist_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/a4_clist/clist", "src/a4_clist/clist_accessor.rs", true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/a4_clist/mod.rs: -------------------------------------------------------------------------------- 1 | mod clist_generate; 2 | mod clist_accessor; 3 | mod use_cil; 4 | mod cil_accessor; 5 | mod cil_generate; 6 | -------------------------------------------------------------------------------- /docchi_manual/src/a4_clist/use_cil.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use crate::a4_clist::cil_accessor::RootIntf; 5 | 6 | //#[test] 7 | fn cil_test() -> Result<()> { 8 | let root_obj : RootObject = json_dir_to_root("src/a4_clist/cil", false)?; 9 | 10 | let root = RootIntf::new(root_obj); 11 | 12 | // Iterates the CList 13 | for item in root.clist().iter(){ 14 | 15 | // Gets the inner list from the item. 16 | let il = item.inner_list(); 17 | println!("len {}", il.len()); 18 | // When inner_list is omitted in the source, len == 0 19 | 20 | // Iterates the inner list. 21 | for item in il.iter(){ 22 | println!("item name is {}", item.name()); 23 | } 24 | } 25 | // Output: 26 | // len 2 27 | // item name is p 28 | // item name is q 29 | // len 0 30 | Ok(()) 31 | } -------------------------------------------------------------------------------- /docchi_manual/src/a5_mlist/mil/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | // Inner MList is named "Mil", which is "Mut Inner List". 3 | 4 | // Basically, changing C to M works, because they are facially very similar. 5 | 6 | // Internally, MList and Mil uses int-keyed LinkedHashMap, which is a hashmap whose items are linked list nodes, 7 | // so it has sequential order. 8 | 9 | // It's items have ID number, which is auto-increment, and assigned automatically. 10 | // The ID is the key, so searching items by ID in the list is very fast(because it's also a hashmap). 11 | // To calculate diff, we compare items with the same ID. 12 | 13 | // Let's see how to use it in the next section. 14 | 15 | mlist : ["MList",[{ 16 | val : 0, 17 | inner_list : ["MilDef",[{ 18 | name : "x", 19 | }]] 20 | }], 21 | { 22 | val : 1, 23 | inner_list : ["Mil", 24 | { 25 | name : "p", 26 | }, 27 | { 28 | name : "q", 29 | } 30 | ] 31 | }, 32 | { 33 | val : 2, 34 | //inner_list omitted 35 | }, 36 | ], 37 | } -------------------------------------------------------------------------------- /docchi_manual/src/a5_mlist/mil_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn mil_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/a5_mlist/mil", "src/a5_mlist/mil_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/a5_mlist/mlist/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | // MList is a mutable list in Docchi. 3 | // Explanations are reserved for the next section. 4 | 5 | mlist : ["MList",[{ 6 | name : "a", 7 | val : 3, 8 | }], 9 | { 10 | name : "b", 11 | val : 4, 12 | }, 13 | { 14 | //name is omitted 15 | val : 5, 16 | } 17 | ], 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/a5_mlist/mlist_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn clist_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/a5_mlist/mlist", "src/a5_mlist/mlist_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/a5_mlist/mod.rs: -------------------------------------------------------------------------------- 1 | mod mlist_generate; 2 | mod mlist_accessor; 3 | mod mil_generate; 4 | mod mil_accessor; 5 | mod use_mil; 6 | -------------------------------------------------------------------------------- /docchi_manual/src/a6_table/mod.rs: -------------------------------------------------------------------------------- 1 | mod table_generate; 2 | mod table_accessor; 3 | mod use_table; 4 | -------------------------------------------------------------------------------- /docchi_manual/src/a6_table/table_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn table_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/a6_table/table", "src/a6_table/table_accessor.rs", true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/jsons/json/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | int : 10, 3 | list : [ 4 | "CList", 5 | [{ 6 | v : 0, 7 | }], 8 | { 9 | v : 1, 10 | } 11 | ], 12 | string : "aaaaa" 13 | } -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/jsons/splitted/int.json5: -------------------------------------------------------------------------------- 1 | 10 -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/jsons/splitted/list.json5: -------------------------------------------------------------------------------- 1 | [ 2 | "CList", 3 | [{ 4 | v : 0, 5 | }], 6 | { 7 | v : 1, 8 | } 9 | ] -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/jsons/splitted/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/jsons/splitted/string.json5: -------------------------------------------------------------------------------- 1 | "aaaaa" -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/mod.rs: -------------------------------------------------------------------------------- 1 | mod split_src_test; -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/split_src.md: -------------------------------------------------------------------------------- 1 | Docchi Src can be split into multiple files. 2 | 3 | The original source is... 4 | ```json5 5 | { 6 | int : 10, 7 | list : [ 8 | "CList", 9 | [{ 10 | v : 0, 11 | }], 12 | { 13 | v : 1, 14 | } 15 | ], 16 | string : "aaaaa" 17 | } 18 | ``` 19 | It can be splitted into 20 | 21 | ``` 22 | ┌─root.json5 23 | ├─int.json5 24 | ├─list.json5 25 | └─string.json5 26 | ``` 27 | "root.json5" is empty. 28 | ```json5 29 | ``` 30 | int.json5 31 | ```json5 32 | 10 33 | ``` 34 | list.json5 35 | ```json5 36 | [ 37 | "CList", 38 | [{ 39 | v : 0, 40 | }], 41 | { 42 | v : 1, 43 | } 44 | ] 45 | ``` 46 | string.json5 47 | ```json5 48 | "aaaaa" 49 | ``` 50 | All items in "root.json5" can be split into separated files with some exceptions. 51 | 52 | The filename of a split file is considered as a variable name, 53 | and the content is considered as the value. 54 | 55 | Nullable variables can't be separated because "?" can't be used in filenames. -------------------------------------------------------------------------------- /docchi_manual/src/a7_split_docchi_src/split_src_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{json_dir_to_root}; 2 | use anyhow::Result; 3 | 4 | #[test] 5 | fn split_src_test() -> Result<()> { 6 | let json = json_dir_to_root("src/a7_split_docchi_src/jsons/json", true)?; 7 | let splitted = json_dir_to_root("src/a7_split_docchi_src/jsons/splitted", true)?; 8 | 9 | assert_eq!(json.default(), splitted.default()); 10 | Ok(()) 11 | } -------------------------------------------------------------------------------- /docchi_manual/src/b1_save_docchi_files/mod.rs: -------------------------------------------------------------------------------- 1 | mod save_docchi_file_test; 2 | mod save_docchi_files_accessor; 3 | mod save_docchi_files_generate; 4 | mod load_docchi_file; -------------------------------------------------------------------------------- /docchi_manual/src/b1_save_docchi_files/save_docchi_files.md: -------------------------------------------------------------------------------- 1 | Let's save data in Docchi. 2 | 3 | There's two types of save files in Docchi, 4 | "Docchi File" and "Docchi History". 5 | 6 | Docchi File saves the difference from "Docchi Src". 7 | 8 | Simply put, Docchi History saves the difference from the previous save file. 9 | 10 | We'll talk about Docchi History later. Now let's move on. 11 | ```root.json5 12 | { 13 | message : "Hello World" 14 | } 15 | ``` 16 | This is the Docchi Src for this section. 17 | -------------------------------------------------------------------------------- /docchi_manual/src/b1_save_docchi_files/save_docchi_files_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn save_docchi_files_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/b1_save_docchi_files/src_dir","src/b1_save_docchi_files/save_docchi_files_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b1_save_docchi_files/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | message : "Hello World" 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/b2_save_history_files/mod.rs: -------------------------------------------------------------------------------- 1 | mod save_history_file_test; 2 | mod save_history_files_accessor; 3 | mod save_history_files_generate; 4 | mod load_history_file_test; -------------------------------------------------------------------------------- /docchi_manual/src/b2_save_history_files/save_history_files_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn save_history_files_generate() -> Result<()> { 6 | generate_accessor_from_json_dir("src/b2_save_history_files/src_dir", "src/b2_save_history_files/save_history_files_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b2_save_history_files/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | d0 : "aaaaa", 3 | d1 : "aaaaa", 4 | d2 : "aaaaa", 5 | d3 : "aaaaa", 6 | d4 : "aaaaa", 7 | d5 : "aaaaa", 8 | d6 : "aaaaa", 9 | d7 : "aaaaa", 10 | d8 : "aaaaa", 11 | d9 : "aaaaa" 12 | } -------------------------------------------------------------------------------- /docchi_manual/src/b2_save_history_files/whats_docchi_history.md: -------------------------------------------------------------------------------- 1 | 2 | Docchi File can be used like a normal data file, 3 | while Docchi History is intended to handle sequential (often small) changes, 4 | like "undo", "auto-save", etc. 5 | 6 | Basically, if you want to use Docchi History, you should also use 7 | Docchi File to save data permanently. 8 | Otherwise, just retain Docchi History files forever. 9 | If you don't remove, it's permanent (but storage drives have their limits...). 10 | 11 | Docchi History files have dependencies on previously saved files, 12 | so removing single file is basically impossible, and retaining only single file is also impossible. 13 | 14 | You must remove all dependants, and retain all dependencies. 15 | This library has a removing policy, "retain last N files and dependencies". 16 | Besides, you can specify files to retain and remove all the other files without their dependencies. 17 | -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/clist_new_adjust_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{json_dir_to_root, adjust_versions}; 2 | use anyhow::Result; 3 | use crate::b3_1_clist_and_mlist::clist_old_accessor::RootIntf; 4 | 5 | #[test] 6 | fn clilst_new_adjust_test() -> Result<()> { 7 | let old = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/clist_old", true)?; 8 | let new = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/clist_new", true)?; 9 | 10 | let r = adjust_versions(new, old, true)?; 11 | 12 | let r = RootIntf::new(r); 13 | let list = r.list(); 14 | let mut iter = list.iter(); 15 | 16 | assert_eq!(iter.next().unwrap().foo(), 3); 17 | assert_eq!(iter.next().unwrap().foo(), 4); 18 | assert_eq!(iter.next().unwrap().foo(), -1); 19 | assert_eq!(iter.next().unwrap().foo(), 5); 20 | Ok(()) 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/clist_new_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn clilst_new_generate() -> Result<()>{ 6 | generate_accessor_from_json_dir("src/b3_1_clist_and_mlist/jsons/clist_new", "src/b3_1_clist_and_mlist/clist_new_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/clist_old_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn clilst_old_generate() -> Result<()>{ 6 | generate_accessor_from_json_dir("src/b3_1_clist_and_mlist/jsons/clist_old", "src/b3_1_clist_and_mlist/clist_old_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/clist_old_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use anyhow::Result; 3 | use crate::b3_1_clist_and_mlist::clist_old_accessor::RootIntf; 4 | 5 | #[test] 6 | fn clilst_old_test() -> Result<()> { 7 | let old = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/clist_old", true)?; 8 | 9 | let r = RootIntf::new(old); 10 | let list = r.list(); 11 | let mut iter = list.iter(); 12 | 13 | assert_eq!(iter.next().unwrap().foo(), 1); 14 | assert_eq!(iter.next().unwrap().foo(), 2); 15 | assert_eq!(iter.next().unwrap().foo(), 0); 16 | Ok(()) 17 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/clist_new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "CList", 4 | [{ 5 | foo : -1, 6 | }], 7 | { 8 | foo : 3, 9 | }, 10 | { 11 | foo : 4, 12 | }, 13 | { 14 | }, 15 | { 16 | foo : 5 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/clist_old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "CList", 4 | // every list must have the default object. 5 | [{ 6 | //The variables must be defined in the default object with its initial value 7 | foo : 0, 8 | }], 9 | { 10 | foo : 1, 11 | }, 12 | { 13 | foo : 2, 14 | }, 15 | { 16 | //if a value is not written, logically its value is the default value, 17 | //but this object actually doesn't have the value. 18 | //No memory is used and no storage space consumed 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/mlist_new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | mlist : [ 3 | "MList", 4 | [{ 5 | //bar is removed, 6 | baz : 100, // baz's default is changed to 100 7 | qux : -1, //new value "qux" is defined 8 | }], 9 | { 10 | baz : 1001, 11 | qux : 2 12 | }, 13 | { 14 | baz : 1002, 15 | qux : 3 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/mlist_old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | mlist : [ 3 | "MList", 4 | [{ 5 | bar : 0, 6 | baz : 1 7 | }], 8 | { 9 | bar : 1, 10 | baz : 2 11 | }, 12 | { 13 | // not set 14 | baz : 3, 15 | }, 16 | { 17 | bar : 3, 18 | // not set 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/no_data/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/undefiable_list/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list! : [ 3 | "MList", 4 | [{ 5 | v : 1, 6 | }], 7 | { 8 | v : 2 9 | }, 10 | { 11 | v : 3 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/undefiable_list_separated/list!.json5: -------------------------------------------------------------------------------- 1 | [ 2 | "MList", 3 | [{ 4 | v: 1, 5 | }], 6 | { 7 | v: 2 8 | }, 9 | { 10 | v: 3 11 | } 12 | ] -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/jsons/undefiable_list_separated/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/mlist_new_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn mlilst_new_generate() -> Result<()>{ 6 | generate_accessor_from_json_dir("src/b3_1_clist_and_mlist/jsons/mlist_new", "src/b3_1_clist_and_mlist/mlist_new_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/mlist_old_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::intf::generate_accessor_from_json_dir; 3 | 4 | #[test] 5 | fn mlilst_old_generate() -> Result<()>{ 6 | generate_accessor_from_json_dir("src/b3_1_clist_and_mlist/jsons/mlist_old","src/b3_1_clist_and_mlist/mlist_old_accessor.rs",true)?; 7 | Ok(()) 8 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/mlist_old_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use anyhow::Result; 3 | use crate::b3_1_clist_and_mlist::mlist_old_accessor::RootIntf; 4 | 5 | #[test] 6 | fn mlist_old_test() -> Result<()> { 7 | let old = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/mlist_old", true)?; 8 | 9 | let mut r = RootIntf::new(old); 10 | let mut list = r.mlist_mut(); 11 | let mut iter = list.iter(); 12 | 13 | if let Some((_id, item)) = iter.next(){ 14 | assert_eq!(item.bar(), 1); 15 | assert_eq!(item.baz(), 2); 16 | } 17 | if let Some((_id, item)) = iter.next(){ 18 | assert_eq!(item.bar(), 0); // default value 19 | assert_eq!(item.baz(), 3); 20 | } 21 | if let Some((_id, item)) = iter.next(){ 22 | assert_eq!(item.bar(), 3); 23 | assert_eq!(item.baz(), 1); // default value 24 | } 25 | Ok(()) 26 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/mod.rs: -------------------------------------------------------------------------------- 1 | mod clist_new_accessor; 2 | mod clist_new_adjust_test; 3 | mod clist_new_generate; 4 | mod clist_old_accessor; 5 | mod clist_old_generate; 6 | mod clist_old_test; 7 | mod mlist_new_accessor; 8 | mod mlist_new_adjust_test; 9 | mod mlist_new_generate; 10 | mod mlist_old_accessor; 11 | mod mlist_old_generate; 12 | mod mlist_old_test; 13 | mod undefiable_list_generate; 14 | mod undefiable_list_accessor; 15 | mod undefiable_list_test; -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/undefiable_list_generate.rs: -------------------------------------------------------------------------------- 1 | 2 | use docchi::intf::{generate_accessor_from_json_dir}; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn undefiable_list_generate() -> Result<()>{ 7 | generate_accessor_from_json_dir("src/b3_1_clist_and_mlist/jsons/undefiable_list_separated","src/b3_1_clist_and_mlist/undefiable_list_accessor.rs",true)?; 8 | Ok(()) 9 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_1_clist_and_mlist/undefiable_list_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{json_dir_to_root, adjust_versions}; 2 | use anyhow::Result; 3 | use crate::b3_1_clist_and_mlist::undefiable_list_accessor::RootIntf; 4 | 5 | #[test] 6 | fn undefiable_list_test() -> Result<()> { 7 | let old = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/no_data", true)?; 8 | let new = json_dir_to_root("src/b3_1_clist_and_mlist/jsons/undefiable_list_separated", true)?; 9 | 10 | // We call "adjust_versions" manually here. 11 | // "load_docchi_file"/"load_history_file" automatically adjusts versions, so calling this manually isn't necessary. 12 | let r = adjust_versions(new, old, true)?; 13 | 14 | let mut r = RootIntf::new(r); 15 | //"list" is undefined, therefore it returns None. 16 | assert!(r.list().is_none()); 17 | let a = r.list_mut(); 18 | // When "list_mut" is called for the first time, an empty list is created and inserted, and the list is returned. 19 | assert_eq!(a.len(), 0); 20 | Ok(()) 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/conversion_generate.rs: -------------------------------------------------------------------------------- 1 | 2 | use docchi::intf::{generate_accessor_from_json_dir}; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn generate_old() -> Result<()>{ 7 | generate_accessor_from_json_dir("src/b3_conversion/jsons/old", "src/b3_conversion/old_accessor.rs",true)?; 8 | Ok(()) 9 | } 10 | #[test] 11 | fn generate_new() -> Result<()>{ 12 | generate_accessor_from_json_dir("src/b3_conversion/jsons/new", "src/b3_conversion/new_accessor.rs",true)?; 13 | Ok(()) 14 | } 15 | #[test] 16 | fn generate_new2() -> Result<()>{ 17 | generate_accessor_from_json_dir("src/b3_conversion/jsons/new2", "src/b3_conversion/new2_accessor.rs",true)?; 18 | Ok(()) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/conversion_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{adjust_versions, json_dir_to_root}; 2 | use super::old_accessor as old_accessor; 3 | use super::new_accessor as new_accessor; 4 | use crate::b3_conversion::new_accessor_wrapper::NewWrapper; 5 | use anyhow::Result; 6 | 7 | #[test] 8 | fn conversion_test() -> Result<()>{ 9 | let old = json_dir_to_root("src/b3_conversion/jsons/old", true)?; 10 | let new = json_dir_to_root("src/b3_conversion/jsons/new", true)?; 11 | let r = adjust_versions(new, old, true)?; 12 | let r = new_accessor::RootIntf::new(r); 13 | let r = NewWrapper::new(r); 14 | assert_eq!(r.new_value(), 100); 15 | 16 | let old = json_dir_to_root("src/sample_test/sample_code_json/version_aware/old", true)?; 17 | let mut old = old_accessor::RootIntf::new(old); 18 | old.set_old_value(2); 19 | 20 | let new = json_dir_to_root("src/sample_test/sample_code_json/version_aware/new", true)?; 21 | let r = adjust_versions(new, old.deconstruct(), true)?; 22 | let r = new_accessor::RootIntf::new(r); 23 | let r = NewWrapper::new(r); 24 | assert_eq!(r.new_value(), 20); 25 | Ok(()) 26 | } 27 | -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/jsons/new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | "oldValue?" : ["Int", null], 3 | "newValue!" : 100, 4 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/jsons/new2/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | "oldValue?" : ["Int", null], 3 | "newValue!?" : ["Int", null], 4 | "newValue2!" : 280, 5 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/jsons/old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | oldValue : 10, 3 | } -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/mod.rs: -------------------------------------------------------------------------------- 1 | mod new_accessor; 2 | mod new2_accessor; 3 | mod new_accessor_wrapper; 4 | mod new2_accessor_wrapper; 5 | mod conversion_generate; 6 | mod conversion_test; 7 | mod old_accessor; -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/new_accessor_wrapper.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::structs::{UndefOr, NullOr}; 2 | use crate::b3_conversion::new_accessor::RootIntf; 3 | 4 | pub(crate) struct NewWrapper { 5 | root : RootIntf 6 | } 7 | 8 | impl NewWrapper { 9 | pub fn new(root: RootIntf) -> NewWrapper { NewWrapper { root } } 10 | 11 | pub fn new_value(&self) -> i64 { 12 | Self::new_value_impl(&self.root) 13 | } 14 | 15 | fn new_value_impl(root: &RootIntf) -> i64 { 16 | match root.new_value() { 17 | //If data is the old version, the variable "new_value" will be "undefined" because it was not defined at the time. 18 | UndefOr::Undefined => { 19 | match root.old_value(){ 20 | NullOr::Null => root.new_value_def_val().into_value().unwrap(), 21 | NullOr::Val(v) => v * 10, //new_value is ten times bigger than the old value 22 | } 23 | }, 24 | UndefOr::Val(v) => { 25 | v 26 | } 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /docchi_manual/src/b3_conversion/old_accessor.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::intf::*; 2 | use docchi::core::structs::*; 3 | unsafe impl Send for RootIntf {} 4 | unsafe impl Sync for RootIntf {} 5 | #[derive(Debug)] 6 | pub struct RootIntf{ 7 | root : Box, 8 | ptr : RootObjectPtr, 9 | } 10 | impl RootIntf{ 11 | pub fn new(obj : RootObject) -> RootIntf{ 12 | let mut root = Box::new(obj); 13 | let ptr = RootObjectPtr::new(root.as_mut()); 14 | RootIntf { root, ptr } 15 | } 16 | pub fn root_obj_ref(&self) -> &RootObject{ self.root.as_ref() } 17 | pub fn root_obj_ref_mut(&mut self) -> &mut RootObject{ self.root.as_mut() } 18 | pub fn deconstruct(self) -> RootObject{ *self.root } 19 | 20 | pub fn old_value(&self) -> i64{ 21 | let qv = root::get_int(self.ptr, "oldValue").unwrap(); 22 | qv.into_value().unwrap() 23 | } 24 | pub fn old_value_def_val(&self) -> i64{ 25 | let qv = root::get_int_def(self.ptr, "oldValue").unwrap(); 26 | qv.into_value().unwrap() 27 | } 28 | pub fn set_old_value(&mut self, old_value : i64){ 29 | root::set_int(self.ptr, "oldValue", Qv::Val(old_value)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docchi_manual/src/lib.rs: -------------------------------------------------------------------------------- 1 | //#![warn(unused_crate_dependencies)] 2 | 3 | 4 | 5 | #[cfg(test)]#[allow(dead_code)] mod sample_test; 6 | 7 | 8 | #[cfg(test)]#[allow(dead_code)]mod a3_docchi_langs_basics; 9 | #[cfg(test)]#[allow(dead_code)]mod a4_clist; 10 | #[cfg(test)]#[allow(dead_code)]mod a5_mlist; 11 | #[cfg(test)]#[allow(dead_code)]mod a6_table; 12 | #[cfg(test)]#[allow(dead_code)]mod a7_split_docchi_src; 13 | #[cfg(test)]#[allow(dead_code)]mod b1_save_docchi_files; 14 | #[cfg(test)]#[allow(dead_code)]mod b2_save_history_files; 15 | #[cfg(test)]#[allow(dead_code)]mod b3_conversion; 16 | #[cfg(test)]#[allow(dead_code)]mod b3_1_clist_and_mlist; 17 | #[cfg(test)]mod make_manual; 18 | #[cfg(test)]#[allow(dead_code)]mod a1_hello_world; 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/get_content.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::path::Path; 3 | 4 | pub(crate) fn get_content(src : &str) -> Result{ 5 | println!("{}", src); 6 | let s = std::fs::read_to_string(format!("src/{}", src))?; 7 | let path = Path::new(src); 8 | let ext = path.extension().unwrap().to_string_lossy().to_string(); 9 | let s = match ext.as_str(){ 10 | "json5" => format!("```json5\n{}\n```", s), 11 | "rs" => format!("```rust\n{}\n```", s), 12 | "md" => s, 13 | _ => unreachable!(), 14 | }; 15 | Ok(s) 16 | } 17 | 18 | 19 | 20 | pub(crate) fn get_md_filename(src : &str) -> Result{ 21 | Ok(format!("{}.md", src.replace('/',"_"))) 22 | } -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/make_manual.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::json_dir_to_root; 3 | use crate::make_manual::manual_accessor::RootIntf; 4 | use crate::make_manual::manual_builder::ManualBuilder; 5 | 6 | #[test] 7 | fn make_manual() -> Result<()>{ 8 | let manual_dir = "manual"; 9 | std::fs::remove_dir_all(manual_dir).ok(); 10 | std::fs::create_dir(manual_dir).unwrap(); 11 | 12 | let r = json_dir_to_root("src/make_manual/manual", false)?; 13 | let r = RootIntf::new(r); 14 | let mut builder = ManualBuilder::new(); 15 | 16 | for item in r.list().iter(){ 17 | builder.add(item.title().to_string(), item.src().map(|s| s.to_string())); 18 | } 19 | builder.build(manual_dir)?; 20 | Ok(()) 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/manual_generate.rs: -------------------------------------------------------------------------------- 1 | 2 | use docchi::intf::{generate_accessor_from_json_dir}; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn generate_old() -> Result<()>{ 7 | generate_accessor_from_json_dir("src/make_manual/manual", "src/make_manual/manual_accessor.rs",true)?; 8 | Ok(()) 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/mod.rs: -------------------------------------------------------------------------------- 1 | mod make_manual; 2 | mod manual_generate; 3 | #[allow(dead_code)]mod manual_accessor; 4 | mod manual_builder; 5 | mod make_index_page; 6 | mod make_page; 7 | mod get_content; 8 | mod write_page; -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/sample/a.md: -------------------------------------------------------------------------------- 1 | [index](index.md) 2 | [next](b.md) 3 | 4 | HogeHoge -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/sample/b.md: -------------------------------------------------------------------------------- 1 | [prev](a.md) 2 | [index](index.md) -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/sample/index.md: -------------------------------------------------------------------------------- 1 | Hogehoge 2 | 3 | 1. [Hoge](a.md) 4 | 5 | ## [Huga](b.md) 6 | 7 | ### [3.1 Hego](c.md) 8 | #### [3.1.1 Hugego](d.md) 9 | ##### [3.1.1.1 Bonbabon](e.md) -------------------------------------------------------------------------------- /docchi_manual/src/make_manual/write_page.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use anyhow::Result; 3 | use crate::make_manual::get_content::{get_md_filename}; 4 | 5 | pub(crate) fn write_page

>(src : &str, page : &str, manual_dir : P) -> Result<()>{ 6 | let path = manual_dir.as_ref().join(get_md_filename(src)?); 7 | std::fs::write(path, page)?; 8 | Ok(()) 9 | } 10 | 11 | pub(crate) fn write_index_page

>(page : &str, manual_dir : P) -> Result<()>{ 12 | let path = manual_dir.as_ref().join("index.md"); 13 | std::fs::write(path, page)?; 14 | Ok(()) 15 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #[cfg(test)] 5 | #[allow(dead_code)] 6 | mod sample_code; 7 | 8 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/clist_new_adjust_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{json_dir_to_root, adjust_versions}; 2 | use crate::sample_test::sample_code::clist_new_accessor::{RootIntf}; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn clilst_new_adjust_test() -> Result<()> { 7 | let old = json_dir_to_root("src/sample_test/sample_code_json/clist_old", true)?; 8 | let new = json_dir_to_root("src/sample_test/sample_code_json/clist_new", true)?; 9 | 10 | let r = adjust_versions(new, old, true)?; 11 | 12 | let r = RootIntf::new(r); 13 | let list = r.list(); 14 | let mut iter = list.iter(); 15 | 16 | assert_eq!(iter.next().unwrap().foo(), 3); 17 | assert_eq!(iter.next().unwrap().foo(), 4); 18 | assert_eq!(iter.next().unwrap().foo(), -1); 19 | assert_eq!(iter.next().unwrap().foo(), 5); 20 | Ok(()) 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/clist_new_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn clilst_new_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/clist_new", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/clist_new_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/clist_old_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn clilst_old_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/clist_old", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/clist_old_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/clist_old_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use crate::sample_test::sample_code::clist_old_accessor::RootIntf; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn clilst_old_test() -> Result<()> { 7 | let old = json_dir_to_root("src/sample_test/sample_code_json/clist_old", true)?; 8 | 9 | let r = RootIntf::new(old); 10 | let list = r.list(); 11 | let mut iter = list.iter(); 12 | 13 | assert_eq!(iter.next().unwrap().foo(), 1); 14 | assert_eq!(iter.next().unwrap().foo(), 2); 15 | assert_eq!(iter.next().unwrap().foo(), 0); 16 | Ok(()) 17 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/mlist_new_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn mlilst_new_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/mlist_new", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/mlist_new_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/mlist_old_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn mlilst_old_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/mlist_old", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/mlist_old_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/mlist_old_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use crate::sample_test::sample_code::mlist_old_accessor::RootIntf; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn mlilst_old_test() -> Result<()> { 7 | let old = json_dir_to_root("src/sample_test/sample_code_json/mlist_old", true)?; 8 | 9 | let mut r = RootIntf::new(old); 10 | let mut list = r.mlist_mut(); 11 | let mut iter = list.iter(); 12 | 13 | if let Some((_id, item)) = iter.next(){ 14 | assert_eq!(item.bar(), 1); 15 | assert_eq!(item.baz(), 2); 16 | } 17 | if let Some((_id, item)) = iter.next(){ 18 | assert_eq!(item.bar(), 0); // default value 19 | assert_eq!(item.baz(), 3); 20 | } 21 | if let Some((_id, item)) = iter.next(){ 22 | assert_eq!(item.bar(), 3); 23 | assert_eq!(item.baz(), 1); // default value 24 | } 25 | Ok(()) 26 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/mod.rs: -------------------------------------------------------------------------------- 1 | mod version_awareness_generate; 2 | mod version_awareness_accessor; 3 | mod version_awareness_accessor_wrapper; 4 | mod version_awareness_accessor2; 5 | mod version_awareness_test; 6 | mod version_awareness_accessor_wrapper2; 7 | mod clist_old_test; 8 | mod clist_old_accessor; 9 | mod clist_old_generate; 10 | mod clist_new_generate; 11 | mod clist_new_accessor; 12 | mod clist_new_adjust_test; 13 | mod mlist_old_test; 14 | mod mlist_new_adjust_test; 15 | mod mlist_old_generate; 16 | mod mlist_old_accessor; 17 | mod mlist_new_accessor; 18 | mod mlist_new_generate; 19 | 20 | mod ref1_generate; 21 | mod ref1_accessor; 22 | mod ref1_test; 23 | mod ref2_test; 24 | mod ref2_generate; 25 | mod ref2_accessor; 26 | mod ref2_wrapper; 27 | mod rpg2_accessor; 28 | mod rpg2_generate; 29 | mod rpg2_test_nottest; 30 | mod rpg2_accessor_wrapper; 31 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/ref1_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn ref1_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/ref1", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/ref1_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/ref1_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use crate::sample_test::sample_code::ref1_accessor::RootIntf; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn ref1_test() -> Result<()> { 7 | let old = json_dir_to_root("src/sample_test/sample_code_json/ref1", true)?; 8 | 9 | let r = RootIntf::new(old); 10 | let list = r.list(); 11 | //mlist is linked-hash-map, which is hashtable whose items are doubly-linked-list-node. 12 | //so first() and last() can be done instantly, but getting middle items are slow, 13 | //unless you use find_by_id instead. 14 | //Linked-hash-map is also hashmap, so you can find items by key(ID) super fast. 15 | let item = list.last().unwrap(); 16 | assert_eq!(item.ref_table_a().foo(), 33); 17 | 18 | Ok(()) 19 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/ref2_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn ref2_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/ref2", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/ref2_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/ref2_test.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use crate::sample_test::sample_code::ref2_accessor::RootIntf; 3 | use anyhow::Result; 4 | 5 | #[test] 6 | fn ref2_test() -> Result<()> { 7 | let old = json_dir_to_root("src/sample_test/sample_code_json/ref2", true)?; 8 | 9 | let r = RootIntf::new(old); 10 | let list = r.list(); 11 | 12 | let item = list.last().unwrap(); 13 | assert_eq!(item.ref_table_a().foo(), 33); 14 | Ok(()) 15 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/ref2_wrapper.rs: -------------------------------------------------------------------------------- 1 | use crate::sample_test::sample_code::ref2_accessor::ListMItem; 2 | use docchi::core::structs::NullOr; 3 | 4 | pub(crate) struct Ref2Wrapper{ 5 | item : ListMItem 6 | } 7 | 8 | impl Ref2Wrapper { 9 | pub fn new(item: ListMItem) -> Ref2Wrapper { Ref2Wrapper { item } } 10 | 11 | pub fn foo(&self) -> i64{ 12 | match self.item.foo(){ 13 | NullOr::Null =>{ 14 | // When it's null, the referenced value is returned 15 | self.item.ref_table_a().foo() 16 | }, 17 | NullOr::Val(v) =>{ 18 | // If it's updated, the updated value is returned 19 | v 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/rpg2_accessor_wrapper.rs: -------------------------------------------------------------------------------- 1 | use crate::sample_test::sample_code::rpg2_accessor::{ItemsMItem, ItemsEnum}; 2 | 3 | pub trait ItemUtil{ 4 | fn price(&self) -> i64; 5 | } 6 | 7 | impl ItemUtil for ItemsMItem{ 8 | fn price(&self) -> i64 { 9 | match self.get_enum(){ 10 | ItemsEnum::Herb(h) =>{ h.price() } 11 | ItemsEnum::Sword(s) =>{ s.price() } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/rpg2_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::json_dir_to_root; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn rpg2_generate() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/rpg2", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/rpg2_accessor.rs", 11 | &ans.to_string(), 12 | ).unwrap(); 13 | } 14 | Err(_e) => { 15 | assert!(false); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/rpg2_test_nottest.rs: -------------------------------------------------------------------------------- 1 | // use docchi::core::json_dir_to_root; 2 | // use crate::sample_test::sample_code::rpg2_accessor::{RootIntf, ItemsEnum}; 3 | // use anyhow::Result; 4 | // use crate::sample_test::sample_code::rpg2_accessor_wrapper::ItemUtil; 5 | // 6 | // 7 | // fn rpg2_test_nottest() -> Result<()> { 8 | // let r = json_dir_to_root("src/sample_test/sample_code_json/rpg2", true)?; 9 | // 10 | // let r = RootIntf::new(r); 11 | // 12 | // for (_id, pc) in r.pc_list().iter(){ 13 | // for (_id, item) in pc.items().iter(){ 14 | // format!("the price is {}", item.price()); 15 | // match item.get_enum(){ 16 | // ItemsEnum::Sword(s) =>{ 17 | // format!("the attack power is {}", s.attack()); 18 | // }, 19 | // ItemsEnum::Herb(h) =>{ 20 | // format!("the heal power is {}", h.restore()); 21 | // } 22 | // } 23 | // } 24 | // } 25 | // 26 | // Ok(()) 27 | // } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/version_awareness_accessor_wrapper.rs: -------------------------------------------------------------------------------- 1 | use crate::sample_test::sample_code::version_awareness_accessor::RootIntf; 2 | use docchi::core::structs::{UndefOr, NullOr}; 3 | 4 | pub(crate) struct VeraAccessorWrapper{ 5 | root : RootIntf 6 | } 7 | 8 | impl VeraAccessorWrapper { 9 | pub fn new(root: RootIntf) -> VeraAccessorWrapper { VeraAccessorWrapper { root } } 10 | 11 | pub fn new_value(&self) -> i64 { 12 | Self::new_value_impl(&self.root) 13 | } 14 | 15 | fn new_value_impl(root: &RootIntf) -> i64 { 16 | match root.new_value() { 17 | //If data is old, the variable "new_value" will be "undefined" because it was not defined at the time. 18 | UndefOr::Undefined => { 19 | match root.old_value(){ 20 | NullOr::Null => root.new_value_def_val().into_value().unwrap(), 21 | NullOr::Val(v) => v * 10, //new_value is ten times bigger than the old value 22 | } 23 | }, 24 | UndefOr::Val(v) => { 25 | v 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code/version_awareness_generate.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::{json_dir_to_root}; 2 | use docchi::intf::generate_interface; 3 | 4 | #[test] 5 | fn generate_version_awareness() { 6 | match json_dir_to_root("src/sample_test/sample_code_json/version_aware/new", true) { 7 | Ok(mut a) => { 8 | let ans = generate_interface(&mut a); 9 | std::fs::write( 10 | "src/sample_test/sample_code/version_awareness_accessor.rs", 11 | &ans.to_string(), 12 | ) 13 | .unwrap(); 14 | } 15 | Err(_e) => { 16 | assert!(false); 17 | } 18 | } 19 | } 20 | #[test] 21 | fn generate_version_awareness2() { 22 | match json_dir_to_root("src/sample_test/sample_code_json/version_aware/new2", true) { 23 | Ok(mut a) => { 24 | let ans = generate_interface(&mut a); 25 | std::fs::write( 26 | "src/sample_test/sample_code/version_awareness_accessor2.rs", 27 | &ans.to_string(), 28 | ) 29 | .unwrap(); 30 | } 31 | Err(_e) => { 32 | assert!(false); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/clist_new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "CList", 4 | [{ 5 | foo : -1, 6 | }], 7 | { 8 | foo : 3, 9 | }, 10 | { 11 | foo : 4, 12 | }, 13 | { 14 | }, 15 | { 16 | foo : 5 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/clist_old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "CList", 4 | // every list must have the default object. 5 | [{ 6 | //The variables must be defined in the default object with its initial value 7 | foo : 0, 8 | }], 9 | { 10 | foo : 1, 11 | }, 12 | { 13 | foo : 2, 14 | }, 15 | { 16 | //if a value is not written, logically its value is the default value, 17 | //but this object actually doesn't have the value. 18 | //No memory is used and no storage space consumed 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/mlist_new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | mlist : [ 3 | "MList", 4 | [{ 5 | //bar is removed, 6 | baz : 100, // baz's default is changed to 100 7 | qux : -1, //new value "qux" is defined 8 | }], 9 | { 10 | baz : 1001, 11 | qux : 2 12 | }, 13 | { 14 | baz : 1002, 15 | qux : 3 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/mlist_old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | mlist : [ 3 | "MList", 4 | [{ 5 | bar : 0, 6 | baz : 1 7 | }], 8 | { 9 | bar : 1, 10 | baz : 2 11 | }, 12 | { 13 | // not set 14 | baz : 3, 15 | }, 16 | { 17 | bar : 3, 18 | // not set 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/ref1/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "MList", 4 | [{ 5 | Ref : { 6 | //Ref's initial value must be a ID, empty string, or null 7 | //If it's empty string, you must set ID, otherwise an error will occur. 8 | tableA : "", 9 | }, 10 | bar : -1, 11 | }], 12 | { 13 | Ref : { 14 | tableA : "item2", //reference item2 of the table below 15 | //IDs must be exists, otherwise an error will occur. 16 | }, 17 | //bar is not set 18 | }, 19 | { 20 | Ref : { 21 | tableA : "item1" 22 | }, 23 | bar : 30, 24 | } 25 | ], 26 | tableA : [ 27 | "Table", 28 | [{ 29 | foo : 0 30 | }], 31 | { 32 | ID : "item1", 33 | foo : 33, 34 | }, 35 | { 36 | ID : "item2", 37 | //not set 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/ref2/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | list : [ 3 | "MList", 4 | [{ 5 | Ref : { 6 | tableA : "", 7 | }, 8 | "foo?" : ["Int",null], 9 | }], 10 | { 11 | Ref : { 12 | tableA : "item1", 13 | }, 14 | // The value is updated here 15 | foo : 22, 16 | }, 17 | ], 18 | tableA : [ 19 | "Table", 20 | [{ 21 | foo : 0 22 | }], 23 | { 24 | ID : "item1", 25 | foo : 33, 26 | }, 27 | ] 28 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/rpg1/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | pcList : [ 3 | "MList", 4 | [{ 5 | Ref : { 6 | race : "", 7 | class : "", 8 | }, 9 | name : "", 10 | }], 11 | { 12 | Ref : { 13 | race : "elf", 14 | class : "mage", 15 | }, 16 | name : "Elvis", 17 | }, 18 | { 19 | Ref : { 20 | race : "dwarf", 21 | class : "fighter", 22 | }, 23 | name : "George", 24 | }, 25 | ], 26 | race : [ 27 | "Table", 28 | [{ 29 | strength : 0, 30 | intelligence : 0, 31 | }], 32 | { 33 | ID : "elf", 34 | strength : 35, 35 | intelligence : 50, 36 | }, 37 | { 38 | ID : "dwarf", 39 | strength : 55, 40 | intelligence : 30, 41 | } 42 | ], 43 | class : [ 44 | "Table", 45 | [{ 46 | attack : 0, 47 | magic : 0, 48 | }], 49 | { 50 | ID : "fighter", 51 | attack : 50, 52 | magic : 0, 53 | }, 54 | { 55 | ID : "mage", 56 | attack : 5, 57 | magic : 30, 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/rpg2/herb.json5: -------------------------------------------------------------------------------- 1 | [ 2 | "Table", 3 | [{ 4 | restore : 0, 5 | price : 0, 6 | }], 7 | { 8 | ID : "low", 9 | restore : 30, 10 | price : 10, 11 | }, 12 | { 13 | ID : "middle", 14 | restore : 80, 15 | price : 50, 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/rpg2/sword.json5: -------------------------------------------------------------------------------- 1 | [ 2 | "Table", 3 | [{ 4 | attack : 0, 5 | price : 0, 6 | }], 7 | { 8 | ID : "bronze", 9 | attack : 10, 10 | price : 100, 11 | }, 12 | { 13 | ID : "iron", 14 | attack : 40, 15 | price :500, 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/version_aware/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dochy-ksti/docchi/ba87777af3ecacb24b097fee8ffaa852bbcc20ff/docchi_manual/src/sample_test/sample_code_json/version_aware/a.txt -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/version_aware/new/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | "oldValue?" : ["Int", null], 3 | "newValue!" : 100, 4 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/version_aware/new2/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | "oldValue?" : ["Int", null], 3 | "newValue!?" : ["Int", null], 4 | "newValue2!" : 280, 5 | } -------------------------------------------------------------------------------- /docchi_manual/src/sample_test/sample_code_json/version_aware/old/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | oldValue : 10, 3 | } -------------------------------------------------------------------------------- /docchi_temporal_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_temporal_test" 3 | version = "0.1.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | 9 | [dependencies] 10 | # docchi_core = { path="../docchi_core" } 11 | docchi = { path="../../docchi" } 12 | bitvec = "0.22.3" 13 | rand = "0.8.4" 14 | rayon = "1.5.1" 15 | anyhow = "1.0" -------------------------------------------------------------------------------- /docchi_temporal_test/src/benchan/mod.rs: -------------------------------------------------------------------------------- 1 | mod benchanmark; 2 | mod threadpool_bench; -------------------------------------------------------------------------------- /docchi_temporal_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | //#![warn(unused_crate_dependencies)] 2 | 3 | #![feature(test)] 4 | extern crate test; 5 | 6 | #[cfg(test)] 7 | #[allow(dead_code)] 8 | mod siyou; 9 | 10 | #[cfg(test)] 11 | #[allow(dead_code)] 12 | mod temporal_test; 13 | 14 | 15 | // #[cfg(test)] 16 | // #[allow(dead_code)] 17 | // mod mlist_mut; 18 | 19 | #[cfg(test)] 20 | #[allow(dead_code)] 21 | mod benchan; 22 | 23 | -------------------------------------------------------------------------------- /docchi_temporal_test/src/siyou/generate_siyou.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | use anyhow::Result; 6 | 7 | //use crate::rust_to_json_new_default; 8 | //use crate::imp::json_to_rust::json_root_to_rust; 9 | //use crate::imp::rust_to_json::root_to_json::root_to_json_new_default; 10 | 11 | ///仕様から生成したコードがコンパイル通るかだけ調べる 12 | #[test] 13 | fn it_works() -> Result<()>{ 14 | 15 | // match json_dir_to_rust("src/test/siyou", true) { 16 | match json_dir_to_root("../docchi_core/src/json_dir/json_siyou", true) { 17 | Ok(mut a) => { 18 | //println!("{:?}", a); 19 | let ans = generate_interface(&mut a); 20 | let source = ans.to_string(); 21 | std::fs::write("src/siyou/siyou_generated.rs", &source)?; 22 | }, 23 | Err(e) => { println!("val 1 {}", e.to_string()); assert!(false); } 24 | } 25 | Ok(()) 26 | } 27 | } -------------------------------------------------------------------------------- /docchi_temporal_test/src/siyou/mod.rs: -------------------------------------------------------------------------------- 1 | mod generate_siyou; 2 | mod siyou_generated; -------------------------------------------------------------------------------- /docchi_temporal_test/src/temporal_test.rs: -------------------------------------------------------------------------------- 1 | use std::time::{UNIX_EPOCH}; 2 | use anyhow::Result; 3 | use docchi::core::structs::NullOr; 4 | 5 | #[test] 6 | fn temporal_test() -> Result<()>{ 7 | let mut v : Vec = vec![]; 8 | for _i in 0..10 { 9 | let now = std::time::SystemTime::now(); 10 | let d = now.duration_since(UNIX_EPOCH)?; 11 | v.push(d.as_nanos()); 12 | } 13 | println!("{:?}", v); 14 | println!("{}", u64::MAX); 15 | Ok(()) 16 | } 17 | 18 | struct Hoge{ 19 | s : Option 20 | } 21 | 22 | impl Hoge{ 23 | pub fn st(&self) -> Option<&str>{ self.s.as_ref().map(|s| s.as_str())} 24 | } 25 | 26 | struct Hoge2{ 27 | s : NullOr 28 | } 29 | 30 | impl Hoge2{ 31 | pub fn st(&self) -> NullOr<&str>{ self.s.as_ref().map(|s| s.as_str())} 32 | } -------------------------------------------------------------------------------- /docchi_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "docchi_test" 3 | version = "0.1.0" 4 | authors = ["juzy "] 5 | edition = "2018" 6 | 7 | license = "MIT OR Apache-2.0" 8 | 9 | [dependencies] 10 | docchi = { path="../../docchi"} 11 | docchi_diff = { path="../docchi_diff"} 12 | docchi_core = { path="../docchi_core"} 13 | # docchi_archiver2 = { path="../docchi_archiver2" } 14 | rand = "0.8.3" 15 | # rayon = "1.5.1" 16 | once_cell = "1.7.2" 17 | parking_lot = "0.11.1" 18 | anyhow = "1.0" 19 | -------------------------------------------------------------------------------- /docchi_test/src/bench/from_le_bytes.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dochy-ksti/docchi/ba87777af3ecacb24b097fee8ffaa852bbcc20ff/docchi_test/src/bench/from_le_bytes.rs -------------------------------------------------------------------------------- /docchi_test/src/bench/mod.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dochy-ksti/docchi/ba87777af3ecacb24b097fee8ffaa852bbcc20ff/docchi_test/src/bench/mod.rs -------------------------------------------------------------------------------- /docchi_test/src/diff/diff_list/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | refed1 : ["Table", 3 | [{ 4 | notImportant : 0 5 | }], 6 | { 7 | ID : "a1" 8 | }, 9 | { 10 | ID : "a2" 11 | }], 12 | 13 | refed2 : ["Table", 14 | [{ 15 | notVeryImportant : 0, 16 | }], 17 | { 18 | ID : "b1", 19 | }, 20 | { 21 | ID : "b2", 22 | } 23 | ], 24 | 25 | list : ["MList", 26 | [{ 27 | Ref : { 28 | refed1 : "a1", 29 | }, 30 | mem : 0, 31 | inList : ["MilDef", 32 | [{ 33 | Ref : { 34 | refed2 : "" 35 | }, 36 | inMem : 0, 37 | inList2 : ["MilDef", 38 | [{ 39 | inMem2 : 0, 40 | }] 41 | ] 42 | }] 43 | ] 44 | }], 45 | { 46 | Ref : { 47 | refed1 : "a1", 48 | }, 49 | mem : 0, 50 | inList : ["Mil", 51 | { 52 | Ref : { 53 | refed2 : "b1", 54 | }, 55 | inList2 : ["Mil", 56 | { 57 | inMem2 : 0, 58 | } 59 | ] 60 | } 61 | ] 62 | }, 63 | ], 64 | 65 | 66 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/diff_param/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | hogeInt : 10, 3 | hogeFloat : 11.0, 4 | hogeString : "hoge", 5 | hogeBool : true, 6 | hogeIntArray : [10, 20, 30], 7 | hogeFloatArray : ["FloatArray", 2.0, 3, 4.0], 8 | hogeBinary : ["Binary", 1,2,3], 9 | "hogeIntHatena?" : 12, 10 | "hogeIntHatenaToNull?" : 120, 11 | "hogeIntHatenaNull?" : ["Int", null], 12 | "hogeUndefined!" : 13, 13 | "hogeUndefinedToUndef!" : 130, 14 | "hogeUndefinedUndef!" : ["Int",undefined], 15 | "hogeUndefNullToNull!?" : 14, 16 | "hogeUndefNullToUndef!?" : 15, 17 | "hogeUndefNullNull!?" : ["Int",null], 18 | "hogeUndefNullUndef!?" : ["Int",undefined], 19 | "hogeUndefNullNullToUndef!?" : ["Int",null], 20 | "hogeUndefNullUndefToNull!?" : ["Int",undefined], 21 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/generate_for_test_big_structure.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use anyhow::Result; 6 | use crate::diff::util::generate_intf_src::generate_intf_src; 7 | 8 | 9 | #[test] 10 | fn generate_for_test_big_structure2() -> Result<()>{ 11 | let json_dir_path = "src/diff/diff_big_structure/"; 12 | let _root_obj = generate_intf_src(json_dir_path, "src/diff/generated_test_big_structure.rs")?; 13 | Ok(()) 14 | } 15 | 16 | 17 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/generate_for_test_list.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use anyhow::Result; 6 | use crate::diff::util::generate_intf_src::generate_intf_src; 7 | 8 | #[test] 9 | fn generate_for_test_list() -> Result<()>{ 10 | let json_dir_path = "src/diff/diff_list"; 11 | let _root_obj = generate_intf_src(json_dir_path, "src/diff/generated_test_list.rs")?; 12 | Ok(()) 13 | } 14 | 15 | 16 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/generate_for_test_params.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use anyhow::Result; 6 | use crate::diff::util::generate_intf_src::generate_intf_src; 7 | 8 | #[test] 9 | fn generate_for_test_params2() -> Result<()>{ 10 | let json_dir_path = "src/diff/diff_param/"; 11 | let _root_obj = generate_intf_src(json_dir_path, "src/diff/generated_test_params.rs")?; 12 | Ok(()) 13 | } 14 | 15 | 16 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/generate_for_test_ref.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use anyhow::Result; 6 | use crate::diff::util::generate_intf_src::generate_intf_src; 7 | 8 | #[test] 9 | fn generate_for_test_ref2() -> Result<()>{ 10 | let json_dir_path = "src/diff/diff_ref/"; 11 | let _root_obj = generate_intf_src(json_dir_path, "src/diff/generated_test_ref.rs")?; 12 | Ok(()) 13 | } 14 | 15 | 16 | } -------------------------------------------------------------------------------- /docchi_test/src/diff/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_params; 2 | 3 | mod util; 4 | mod test_big_structure; 5 | mod generate_for_test_params; 6 | mod generate_for_test_big_structure; 7 | mod generated_test_big_structure; 8 | mod generated_test_params; 9 | mod test_ref; 10 | mod generate_for_test_ref; 11 | mod generated_test_ref; 12 | mod generate_for_test_list; 13 | mod test_list; 14 | mod generated_test_list; 15 | -------------------------------------------------------------------------------- /docchi_test/src/diff/util/generate_intf_src.rs: -------------------------------------------------------------------------------- 1 | use docchi::intf::generate_interface; 2 | use docchi::core::structs::RootObject; 3 | use anyhow::Result; 4 | use docchi::core::json_dir_to_root; 5 | 6 | pub fn generate_intf_src(json_dir_path : &str, src_file_path : &str) -> Result { 7 | let mut root = json_dir_to_root(json_dir_path,true)?; 8 | let source = generate_interface(&mut root); 9 | std::fs::write(src_file_path, &source.to_string_with_cfg_test())?; 10 | 11 | Ok(root) 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /docchi_test/src/diff/util/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generate_intf_src; 2 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/history_accum_test/hello_history_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | 6 | #[test] 7 | fn hello_history_generate() -> Result<()> { 8 | let mut root_obj : RootObject = json_dir_to_root("src/fs_test/history_accum_test/src_dir", true)?; 9 | 10 | let ans = generate_interface(&mut root_obj); 11 | std::fs::write( 12 | "src/fs_test/history_accum_test/hello_history_accessor.rs", 13 | &ans.to_string(), 14 | ).unwrap(); 15 | Ok(()) 16 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/history_accum_test/mod.rs: -------------------------------------------------------------------------------- 1 | mod hello_history_accessor; 2 | mod hello_history_generate; 3 | mod accum_save_test; 4 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/history_accum_test/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | data0 : ["IntArray"], 3 | data1 : ["IntArray"], 4 | data2 : ["IntArray"], 5 | data3 : ["IntArray"], 6 | data4 : ["IntArray"], 7 | data5 : ["IntArray"], 8 | data6 : ["IntArray"], 9 | data7 : ["IntArray"], 10 | data8 : ["IntArray"], 11 | data9 : ["IntArray"], 12 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/history_accum_test/src_dir_copy/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | data0 : ["Binary"], 3 | data1 : ["Binary"], 4 | data2 : ["Binary"], 5 | data3 : ["Binary"], 6 | data4 : ["Binary"], 7 | data5 : ["Binary"], 8 | data6 : ["Binary"], 9 | data7 : ["Binary"], 10 | data8 : ["Binary"], 11 | data9 : ["Binary"], 12 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | mod history_accum_test; 3 | mod test_save_async; 4 | mod test_save_history_vacant; 5 | mod test_save_history_nb; 6 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_save_async_generate; 2 | mod test_save_async; 3 | mod test_save_async_accessor; 4 | mod test_thread; 5 | //mod test_thread; 6 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | data0 : 0, 3 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/test_save_async_accessor.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::intf::*; 2 | use docchi::core::structs::*; 3 | unsafe impl Send for RootIntf {} 4 | unsafe impl Sync for RootIntf {} 5 | #[derive(Debug)] 6 | pub struct RootIntf{ 7 | root : Box, 8 | ptr : RootObjectPtr, 9 | } 10 | impl RootIntf{ 11 | pub fn new(obj : RootObject) -> RootIntf{ 12 | let mut root = Box::new(obj); 13 | let ptr = RootObjectPtr::new(root.as_mut()); 14 | RootIntf { root, ptr } 15 | } 16 | pub fn root_obj_ref(&self) -> &RootObject{ self.root.as_ref() } 17 | pub fn root_obj_ref_mut(&mut self) -> &mut RootObject{ self.root.as_mut() } 18 | pub fn deconstruct(self) -> RootObject{ *self.root } 19 | 20 | pub fn data0(&self) -> i64{ 21 | let qv = root::get_int(self.ptr, "data0").unwrap(); 22 | qv.into_value().unwrap() 23 | } 24 | pub fn data0_def_val(&self) -> i64{ 25 | let qv = root::get_int_def(self.ptr, "data0").unwrap(); 26 | qv.into_value().unwrap() 27 | } 28 | pub fn set_data0(&mut self, data0 : i64){ 29 | root::set_int(self.ptr, "data0", Qv::Val(data0)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/test_save_async_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | 6 | #[test] 7 | fn test_save_async_generate() -> Result<()> { 8 | let mut root_obj : RootObject = json_dir_to_root("src/fs_test/test_save_async/src_dir", true)?; 9 | 10 | let ans = generate_interface(&mut root_obj); 11 | std::fs::write( 12 | "src/fs_test/test_save_async/test_save_async_accessor.rs", 13 | &ans.to_string(), 14 | ).unwrap(); 15 | Ok(()) 16 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/test_thread.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::time::Duration; 3 | //use std::lazy::Lazy; 4 | 5 | use once_cell::sync::Lazy; 6 | 7 | 8 | //use parking_lot::FairMutex as Bmutex; 9 | use parking_lot::Mutex as Bmutex; 10 | //use std::sync::Mutex as Bmutex; 11 | 12 | static VEC_LAZY: Lazy>> = Lazy::new(||{ 13 | Bmutex::new(Vec::new()) 14 | }); 15 | 16 | ///thread::spawnでスレッドはバラバラに実行されることの確認 17 | //#[test] 18 | fn test_thread() -> Result<()> { 19 | 20 | let max = 10; 21 | 22 | 23 | for i in 0..max{ 24 | std::thread::spawn(move||{ 25 | { 26 | let mut v = VEC_LAZY.lock(); 27 | 28 | 29 | std::thread::sleep(Duration::from_millis(100)); 30 | 31 | v.push(format!("{}", i)); 32 | } 33 | 34 | // let mut v = vec_lazy2.lock().unwrap(); 35 | // v.push(format!("{}",i)); 36 | }); 37 | } 38 | 39 | std::thread::sleep(Duration::from_millis(1)); 40 | 41 | let v = VEC_LAZY.lock(); 42 | let hoge : &Vec = &v; 43 | println!("{:?}", hoge); 44 | 45 | //Output: 46 | //["0", "6", "1", "2", "3", "5", "7", "4", "8", "9"] 47 | 48 | 49 | Ok(()) 50 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_async/test_thread_file.dat: -------------------------------------------------------------------------------- 1 | 2 |  -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_nb/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_save_history_async_generate; 2 | mod test_save_history_async; 3 | mod test_save_history_async_accessor; 4 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_nb/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | data0 : 0, 3 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_nb/test_save_history_async_accessor.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::intf::*; 2 | use docchi::core::structs::*; 3 | unsafe impl Send for RootIntf {} 4 | unsafe impl Sync for RootIntf {} 5 | #[derive(Debug)] 6 | pub struct RootIntf{ 7 | root : Box, 8 | ptr : RootObjectPtr, 9 | } 10 | impl RootIntf{ 11 | pub fn new(obj : RootObject) -> RootIntf{ 12 | let mut root = Box::new(obj); 13 | let ptr = RootObjectPtr::new(root.as_mut()); 14 | RootIntf { root, ptr } 15 | } 16 | pub fn root_obj_ref(&self) -> &RootObject{ self.root.as_ref() } 17 | pub fn root_obj_ref_mut(&mut self) -> &mut RootObject{ self.root.as_mut() } 18 | pub fn deconstruct(self) -> RootObject{ *self.root } 19 | 20 | pub fn data0(&self) -> i64{ 21 | let qv = root::get_int(self.ptr, "data0").unwrap(); 22 | qv.into_value().unwrap() 23 | } 24 | pub fn data0_def_val(&self) -> i64{ 25 | let qv = root::get_int_def(self.ptr, "data0").unwrap(); 26 | qv.into_value().unwrap() 27 | } 28 | pub fn set_data0(&mut self, data0 : i64){ 29 | root::set_int(self.ptr, "data0", Qv::Val(data0)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_nb/test_save_history_async_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | 6 | #[test] 7 | fn test_save_history_async_generate() -> Result<()> { 8 | let mut root_obj : RootObject = json_dir_to_root("src/fs_test/test_save_history_nb/src_dir", true)?; 9 | 10 | let ans = generate_interface(&mut root_obj); 11 | std::fs::write( 12 | "src/fs_test/test_save_history_nb/test_save_history_async_accessor.rs", 13 | &ans.to_string(), 14 | ).unwrap(); 15 | Ok(()) 16 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_vacant/mod.rs: -------------------------------------------------------------------------------- 1 | mod test_save_history_vacant_generate; 2 | mod test_save_history_vacant; 3 | mod test_save_history_vacant_accessor; 4 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_vacant/src_dir/root.json5: -------------------------------------------------------------------------------- 1 | { 2 | data0 : 0, 3 | } -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_vacant/test_save_history_vacant_accessor.rs: -------------------------------------------------------------------------------- 1 | use docchi::core::intf::*; 2 | use docchi::core::structs::*; 3 | unsafe impl Send for RootIntf {} 4 | unsafe impl Sync for RootIntf {} 5 | #[derive(Debug)] 6 | pub struct RootIntf{ 7 | root : Box, 8 | ptr : RootObjectPtr, 9 | } 10 | impl RootIntf{ 11 | pub fn new(obj : RootObject) -> RootIntf{ 12 | let mut root = Box::new(obj); 13 | let ptr = RootObjectPtr::new(root.as_mut()); 14 | RootIntf { root, ptr } 15 | } 16 | pub fn root_obj_ref(&self) -> &RootObject{ self.root.as_ref() } 17 | pub fn root_obj_ref_mut(&mut self) -> &mut RootObject{ self.root.as_mut() } 18 | pub fn deconstruct(self) -> RootObject{ *self.root } 19 | 20 | pub fn data0(&self) -> i64{ 21 | let qv = root::get_int(self.ptr, "data0").unwrap(); 22 | qv.into_value().unwrap() 23 | } 24 | pub fn data0_def_val(&self) -> i64{ 25 | let qv = root::get_int_def(self.ptr, "data0").unwrap(); 26 | qv.into_value().unwrap() 27 | } 28 | pub fn set_data0(&mut self, data0 : i64){ 29 | root::set_int(self.ptr, "data0", Qv::Val(data0)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docchi_test/src/fs_test/test_save_history_vacant/test_save_history_vacant_generate.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use docchi::core::structs::RootObject; 3 | use docchi::core::json_dir_to_root; 4 | use docchi::intf::generate_interface; 5 | 6 | //#[test] 7 | fn test_save_history_vacant_generate() -> Result<()> { 8 | let mut root_obj : RootObject = json_dir_to_root("src/fs_test/test_save_history_vacant/src_dir", true)?; 9 | 10 | let ans = generate_interface(&mut root_obj); 11 | std::fs::write( 12 | "src/fs_test/test_save_history_vacant/test_save_history_vacant_accessor.rs", 13 | &ans.to_string(), 14 | ).unwrap(); 15 | Ok(()) 16 | } -------------------------------------------------------------------------------- /docchi_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)]#[allow(dead_code)]mod diff; 2 | 3 | #[cfg(test)]#[allow(dead_code)]mod fs_test; 4 | //mod bench; -------------------------------------------------------------------------------- /mit_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 juzy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /publish.bat: -------------------------------------------------------------------------------- 1 | cd ./docchi_json5 2 | cargo publish 3 | timeout /t 180 > nul 4 | cd ../docchi_compaction 5 | cargo publish 6 | timeout /t 180 > nul 7 | cd ../docchi_archiver2 8 | cargo publish 9 | timeout /t 180 > nul 10 | cd ../docchi_core 11 | cargo publish 12 | timeout /t 180 > nul 13 | cd ../docchi_diff 14 | cargo publish 15 | timeout /t 180 > nul 16 | cd ../docchi_fs 17 | cargo publish 18 | timeout /t 180 > nul 19 | cd ../docchi_intf 20 | cargo publish 21 | timeout /t 180 > nul 22 | cd ../ 23 | cargo publish -------------------------------------------------------------------------------- /roadmap.md: -------------------------------------------------------------------------------- 1 | Currently, we have no intention of breaking change of the API, 2 | but if people use this library, they might request it, 3 | and we hope it happened to sophisticate the API. 4 | 5 | We expect binary format of the Docchi and History files will be changed 6 | in the near future for the loading process to be more concurrent. 7 | 8 | Needs to improve removing process to be durable for sudden power outage. 9 | 10 | Currently, we are creating a sample game, 11 | which is a Ninja TRPG simulator, to prove this library can be used smoothly. -------------------------------------------------------------------------------- /src/intf.rs: -------------------------------------------------------------------------------- 1 | 2 | pub use docchi_intf::generate_interface; 3 | pub use docchi_intf::generate_accessor_from_json_dir; 4 | 5 | pub use docchi_intf::RootSource; 6 | 7 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [Docchi User's Manual](https://github.com/dochy-ksti/docchi/blob/master/docchi_manual/manual/index.md) 2 | //! 3 | //! Docchi is a language, so this API document is not sufficient to explain what it is. 4 | 5 | #![deny(unreachable_pub)] 6 | #![deny(unused_crate_dependencies)] 7 | 8 | pub mod intf; 9 | pub mod core; 10 | pub mod fs; 11 | 12 | 13 | 14 | //TODO: ファイルは一旦tmpファイルに書き出してから書き出してからリネームするようにする 15 | //TODO: フォルダ削除時に途中で強制終了があると中途半端なファイルだけ残り不正な状態になる可能性があるので、まずフォルダ名を変更しフォルダ内のファイルを無効にしてから削除するようにする? 最新ファイルから順々に過去ファイルを消し、最後にフォルダも消す? 16 | //TODO: CopySaveFileToPhase0を作る SaveAsyncを作る 17 | //TODO: バックエンドを変更可能にする。デバッグのためのインメモリ、leveldb-rsを使ってKVPなど。ファイルももっと安全に、フォルダ削除時に新しいファイルから消していくような、構造が壊れない処理を 18 | //TODO: Pathの同一性が怪しいから、Pathを自作のものに置き換える?? 19 | //TODO: 現状max_phaseのload時に派生元をmax_phase-1からにしているが、最新アイテムから派生しても別にいいような気がするんだが・・・ 20 | //TODO: 2回セーブしてロードの繰り返しできちんとHistoryを構成するtestが書きたいので、max_phaseの最新ファイル以外からもロード後に派生できるようにする <-いずれ・・ 21 | 22 | 23 | //TODO: 全部documentationする 24 | //TODO: Redditに出して反応を見る このペースだと何ヶ月かかるんじゃあ・・・ 25 | -------------------------------------------------------------------------------- /並列化仕様.txt: -------------------------------------------------------------------------------- 1 | KVal::Bit(0)をあらかじめ、全部のMListの最初の方に入れる。0の場合並列化なし 2 | 1アイテムごとに何KVal使っているか数えながら、KValリストを作り上げていく。 3 | ある定数(多分1万ぐらい)のKValを1タスクにして、スレッドに分割していく。 4 | アイテムごとに、定数を超えたらタスク分割。1タスクに属するアイテム数は1か2か3かわからないが、中途半端なところでは分割しない。 5 | 分割が発生したら、KVal::Bitの部分を上書きする。KVal::Binaryのdocchi_compaction形式で、 6 | スレッド数、1スレッドのアイテム数*スレッド数。 7 | ここが1万ぐらいになってしまうと、compactionの解析に時間がかかるようになってくるが・・・まあどうでもいいか 8 | 9 | 問題は、10000が大きすぎてテストしづれえなってこと。まあそれもいいや。 10 | 実践の中で大きいデータが出来るはずだから、それをテストデータにする。それまでこれの実装は待つ。 11 | 12 | あとはcompactionの並列化。最初からやっておくべきだったのでは? 13 | ある定数個(多分10000ぐらい)のKValに分割し、それぞれのcompactionバイナリを作る。 14 | 最初に分割数とタスクごとのバイト数を入れる。 15 | ファイルを分割したバイナリのバイト数だけ読み出し、スレッドに送って解析させる。 16 | 読み出しにかかる時間と、解析の時間を並列化させられる。 17 | 実はSSDは(HDDの直列読み出しも)十分に早いので、読出しよりも解析がオーバーヘッドになる 18 | (特にdocchi_compactionはビット単位で保存するので読み出しよりも解析の時間がかかる)。 19 | 20 | これも問題は大きなテストデータが必要になること。 21 | 同じ理由で、実装は実践データが揃うまで待つ。 --------------------------------------------------------------------------------