Alıntı (zafer:1332916021):
> Dosya okuma işlemini hallettiğimize göre sıra geldi JSON dosyasına veri ekleme, güncelleme ve silme operasyonlarına. bu konudaki her türlü yardıma açığım :-D
JSON gibi metin düzenindeki dosyalara ekleme ve silme yapılmaz; bütün dosya baştan yazılır. İstenirse yapılabilir tabii ama çok karmaşık olur. Gerekeceğini sanmıyorum.
Çözüm istemediğini biliyorum ama to() şablonunu JSONValue için özelledim. Aşağıdaki gibi opCast() işlecini yazan yapı ve sınıflarla da kolayca kullanılabiliyor:
import std.stdio;
import std.conv;
import std.json;
import std.traits;
import std.exception;
import std.string;
/* Gözlem: Ne to() bizim işlevimiz, ne de JSONValue bizim türümüz. İkisini
* birleştiren böyle bir işleve hakkımız var mı? Veya: Bize mi kalmış? Aslında
* evet, çünkü eklediğimiz bu işlev kendi modülümüzün isim alanına
* ekleniyor. Karışıklık olursa da tam ismiyle ötekisi tam ismiyle örneğin
* std.conv.to diye çağrılabilir.
*
* (Not: C++ olsa std isim alanına bir şey eklenmesine izin verilmez. (Ama
* kendi türlerimizden oluşan std::pair'leri << ile yazdırmak için bazen
* mecbur kalınır.))
*
* UYARI: Eşleme tabloları unutulmuş!
*/
JSONValue to(Hedef : JSONValue, T)(T değer)
{
JSONValue json;
static if (isSomeString!T) {
json.type = JSON_TYPE.STRING;
json.str = std.conv.to!string(değer);
} else static if (is (T : long)) {
static if (is (T == ulong)) {
/* std.json long türünü kullandığı için ulong'un bazı değerlerini
* tutamaz. Güvenlik amacıyla bu durumu denetlemek için ulong için
* ayrı bir 'static if' koşulu yazıyoruz. */
enforce(değer <= long.max,
format("Veri kaybı: Bir %s değeri olan %s, long'a sığamaz!",
T.stringof, değer));
}
json.type = JSON_TYPE.INTEGER;
json.integer = değer;
} else static if (is (T : real)) {
json.type = JSON_TYPE.FLOAT;
json.floating = değer;
} else static if (isArray!T) {
json.type = JSON_TYPE.ARRAY;
foreach (eleman; değer) {
json.array ~= to!JSONValue(eleman);
}
} else static if (__traits(compiles, cast(JSONValue)değer)) {
json = cast(JSONValue)(değer);
} else {
static assert(false,
"Bu tür JSONValue'ya dönüştürülemez: " ~ T.stringof);
}
return json;
}
unittest
{
import std.typetuple;
/* ulong'un değer aralığının üst yarısı long'a sığmaz. Onun için ayrıca
* deniyoruz. */
to!JSONValue(cast(ulong)0);
to!JSONValue(cast(ulong)long.max);
/* Güvenlik gerçekten işe yarıyor mu? */
bool hataAtıldı_mı = false;
try {
to!JSONValue(ulong.max);
} catch (Exception) {
hataAtıldı_mı = true;
}
enforce(hataAtıldı_mı, "ulong.max için hata atılmadı!");
/* Her temel tür kullanılabilmeli. */
alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long, /* ulong, */
float, double, real,
string, wstring, dstring, char[], wchar[], dchar[],
int[])
Türler;
foreach (Tür; Türler) {
to!JSONValue(Tür.init);
}
}
struct Öğrenci
{
string isim;
ulong numara;
uint[] notlar;
JSONValue opCast(T : JSONValue)() const @property
{
JSONValue[string] üyeler;
üyeler["isim"] = to!JSONValue(isim);
üyeler["numara"] = to!JSONValue(numara);
üyeler["notlar"] = to!JSONValue(notlar);
JSONValue json;
json.object = üyeler;
json.type = JSON_TYPE.OBJECT;
return json;
}
}
JSONValue JSONBelgesi()
{
JSONValue json;
json.type = JSON_TYPE.OBJECT;
return json;
}
void main()
{
auto öğrenciler = [ Öğrenci("Ayşe", 12, [ 90, 100 ]),
Öğrenci("Başak", 34, [ 95, 99 ]) ];
JSONValue belge = JSONBelgesi();
belge.object["öğrenciler"] = to!JSONValue(öğrenciler);
writeln(toJSON(&belge));
}
Çıktısı:
'{"öğrenciler":[{"isim":"Ayşe","numara":12,"notlar":[90,100]},{"isim":"Başak","numara":34,"notlar":[95,99]}]}'
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]