package jx

import 

// ObjIter is decoding object iterator.
type ObjIter struct {
	d        *Decoder
	key      []byte
	err      error
	isBuffer bool
	closed   bool
	comma    bool
}

// ObjIter creates new object iterator.
func ( *Decoder) () (ObjIter, error) {
	if  := .consume('{');  != nil {
		return ObjIter{}, errors.Wrap(, `"{" expected`)
	}
	if  := .incDepth();  != nil {
		return ObjIter{}, 
	}
	if ,  := .more();  != nil {
		return ObjIter{}, 
	}
	.unread()
	return ObjIter{d: , isBuffer: .reader == nil}, nil
}

// Key returns current key.
//
// Key call must be preceded by a call to Next.
func ( *ObjIter) () []byte {
	return .key
}

// Next consumes element and returns false, if there is no elements anymore.
func ( *ObjIter) () bool {
	if .closed || .err != nil {
		return false
	}

	 := .d
	,  := .more()
	if  != nil {
		.err = 
		return false
	}
	if  == '}' {
		.closed = true
		.err = .decDepth()
		return false
	}
	if .comma {
		if  != ',' {
			 := badToken(, .offset()-1)
			.err = errors.Wrap(, `"," expected`)
			return false
		}
	} else {
		.unread()
	}

	,  := .str(value{raw: .isBuffer})
	if  != nil {
		.err = errors.Wrap(, "field name")
		return false
	}
	if  := .consume(':');  != nil {
		.err = errors.Wrap(, `":" expected`)
		return false
	}
	// Skip whitespace.
	if _,  = .more();  != nil {
		 := badToken(, .offset()-1)
		.err = errors.Wrap(, `"," or "}" expected`)
		return false
	}
	.unread()

	.comma = true
	.key = .buf

	return true
}

// Err returns the error, if any, that was encountered during iteration.
func ( *ObjIter) () error {
	return .err
}